Исправлена продажа множественных экземпляров витринных букетов

Проблема: При продаже 2+ экземпляров одного витринного комплекта возникала
ошибка 'Один из экземпляров уже был продан'. Это происходило потому что
объекты ShowcaseItem проверялись по старому состоянию из памяти.

Причина:
- При вызове sell_showcase_items() передавался список объектов из запроса
- Первый ShowcaseItem менял статус на 'sold' через mark_sold()
- Второй объект в списке все еще имел старый статус из памяти
- Проверка в цикле срабатывала некорректно

Решение:
- Перезагружаем ВСЕ ShowcaseItem из БД с блокировкой перед обработкой
- Используем select_for_update() для получения актуального статуса
- Теперь каждый экземпляр проверяется по свежим данным из БД
- Защита от race conditions через database-level locking

Результат:
Теперь можно продавать 2+ экземпляра одного букета без ошибок.
This commit is contained in:
2025-12-11 22:14:57 +03:00
parent 741fdc97a8
commit d5e40bb1c8

View File

@@ -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(