Когда несколько пользователей пытаются разместить ставки или совершить покупку одновременно, мне необходимо обеспечить:
- отсутствие двойной траты пользовательского баланса
- отсутствие двойного обновления статуса товара
- последовательное назначение победителя
Моя текущая реализация использует оболочку транзакции:
Код: Выделить всё
return TransactionManager.execute(conn -> {
boolean ok1 = itemDao.updateCurrentPrice(itemId, price, conn);
boolean ok2 = itemDao.updateItemStatus(itemId, ItemStatus.CLOSED, conn);
boolean ok3 = itemDao.updateWinnerId(itemId, userId, conn);
if (!ok1 || !ok2 || !ok3) {
throw new RuntimeException("Transaction failed");
}
return true;
});
Код: Выделить всё
synchronized (user) {
synchronized (item) {
// bidding logic
- SELECT ... FOR UPDATE
- синхронизированных блоков в Java
- или оптимистической блокировки
Мой вопрос:
Достаточно ли использования `SELECT FOR UPDATE` для предотвращения условий гонки в этом случае, или мне также нужна блокировка на уровне Java
Что такое правильный подход для промышленных аукционных систем?