Ответ
Без дополнительных механизмов синхронизации может возникнуть состояние гонки (race condition), приводящее к некорректному уменьшению количества товара (например, вместо уменьшения на 2, уменьшится на 1). Это происходит из-за последовательного чтения и обновления значения разными транзакциями.
Пример проблемного сценария:
- Транзакция A и B читают
quantity = 10. - A вычисляет новое значение:
10 - 1 = 9и обновляет строку. - B, основываясь на старом значении (10), вычисляет
10 - 1 = 9и также обновляет строку. - Итог:
quantity = 9, хотя должно быть8.
Решение: Использовать атомарные операции или пессимистические блокировки.
- Атомарное обновление в одном запросе:
UPDATE products SET quantity = quantity - 1 WHERE id = 123 AND quantity > 0; - Пессимистическая блокировка (SELECT FOR UPDATE):
BEGIN; SELECT quantity FROM products WHERE id = 123 FOR UPDATE; -- Блокировка строки -- Проверка quantity > 0 и логика приложения UPDATE products SET quantity = quantity - 1 WHERE id = 123; COMMIT; - Оптимистическая блокировка (версионирование): Добавить поле
version. Каждое обновление проверяет, не изменилась ли версия с момента чтения.