Есть предмет в корзине, есть метод проверки на его наличие в стороннем сервисе. Метод проверки вызывается при попытке купить предмет. Если она прошла успешно - товар покупается, если нет - выводится ошибка. Время запроса занимает около 10 секунд.
status: 1 - предмет в корзине
status: 2 - предмет проверяется
status: 3 - предмет оплачен
status: 4 - предмет отсутствует в стороннем сервисе
Проблемы:
1) Разумно ли использовать SQL транзакции в данном случае? Начинаю транзакцию, получаю информацию о товаре из БД, запрашиваю его наличие в стороннем сервисе, обновляю товар в БД и только после делаю commit. Как я понимаю, если кто-то другой захочет купить предмет, то он сделать этого не сможет, ибо таблица блокируется на время транзакции.
2) Как можно организовать status: 2 вместе с транзакцией? Ведь когда транзакция начинается, status: 1. Когда транзакция выполнилась, status: 3. Как мне к этому всему привязать промежуточный status: 2?
Из решений приходит в голову только:
1. Начинаю транзакцию, получаю информацию о товаре из БД, делаю проверки, обновляю status: 2 и делаю коммит.
2) Проверяю товар на наличие в стороннем сервисе
3) При успешном/провальном ответе обновляю статус товара без транзакции status: 3/status: 1. Адекватное ли решение?
Неразумно. Сторонний сервис может отвечать минуту-другую. Всё это время в БД будет висеть транзакция. Само по себе это не плохо, но привести может к каким угодно последствиям.
Как можно организовать status: 2 вместе с транзакцией?
Транзакции вам в принципе нужны только для атомарности, т.е. обеспечения консистентного состояния БД при изменении нескольких записей сразу. Например, списать деньги со счета одновременно со сменой статуса на "оплачен". Блокировки таблицы на время создания - это плохо. Запрос "другого пользователя" будет просто висеть. Попробуйте для начала сделать вообще без транзакций, потом по коду посмотрите, какие могут возникать неконситентности. А дальше - по ситуации.