Исправлена продажа множественных экземпляров витринных букетов
Проблема: При продаже 2+ экземпляров одного витринного комплекта возникала ошибка 'Один из экземпляров уже был продан'. Это происходило потому что объекты ShowcaseItem проверялись по старому состоянию из памяти. Причина: - При вызове sell_showcase_items() передавался список объектов из запроса - Первый ShowcaseItem менял статус на 'sold' через mark_sold() - Второй объект в списке все еще имел старый статус из памяти - Проверка в цикле срабатывала некорректно Решение: - Перезагружаем ВСЕ ShowcaseItem из БД с блокировкой перед обработкой - Используем select_for_update() для получения актуального статуса - Теперь каждый экземпляр проверяется по свежим данным из БД - Защита от race conditions через database-level locking Результат: Теперь можно продавать 2+ экземпляра одного букета без ошибок.
This commit is contained in:
@@ -151,7 +151,17 @@ class ShowcaseManager:
|
|||||||
|
|
||||||
try:
|
try:
|
||||||
with transaction.atomic():
|
with transaction.atomic():
|
||||||
for showcase_item in showcase_items:
|
# Собираем ID для перезагрузки с блокировкой
|
||||||
|
showcase_item_ids = [item.id for item in showcase_items]
|
||||||
|
|
||||||
|
# Перезагружаем объекты из БД с блокировкой для актуального статуса
|
||||||
|
showcase_items_locked = list(
|
||||||
|
ShowcaseItem.objects.select_for_update().filter(
|
||||||
|
id__in=showcase_item_ids
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
for showcase_item in showcase_items_locked:
|
||||||
# Проверка статуса перед продажей
|
# Проверка статуса перед продажей
|
||||||
if showcase_item.status == 'sold':
|
if showcase_item.status == 'sold':
|
||||||
raise ValidationError(
|
raise ValidationError(
|
||||||
|
|||||||
Reference in New Issue
Block a user