Предположим, у меня есть SQL-транзакционная финансовая система, но во время транзакции она вызывает внешний не-SQL сервис.
Что делать, например, с потеря питания, когда у нас нет, был ли внешний вызов успешным или нет?
Представим, что на SQL-базе данных и биткойн-кошельке совершается транзакция.
- Начать SQL-транзакцию
- Уменьшить количество наличных денег пользователя
- Отправляйте пользовательские деньги куда-нибудь через биткойн-кошелек
- Совершить
Потеря мощности между шагами 3 и 4 предотвратит транзакцию (без уменьшения наличных денег пользователя), но фактически отправит наши деньги из кошелька.
Второй сценарий заключается в уменьшении денежных средств пользователя и фиксации перед вызовом внешней службы. Но когда потеря питания произойдет после сбоя внешней службы (фактически не отправленной) денег, мы не сможем вернуть средства пользователя после сбоя внешней службы (предположим, что биткойн-кошелек не работает).
В настоящее время я уменьшаю деньги и помечаю транзакцию как «в процессе» (и фиксирую это) перед вызовом внешней службы, затем, если внешняя служба отвечает «ОК», я отмечаю все как успешно завершенное.
Но при потере питания я все еще могу оставаться в ситуации, когда какая-то транзакция после отключения питания помечается как «в процессе», деньги уменьшаются, но я должен вручную смотреть транзакции биткойн-кошелька/блокчейна, действительно ли деньги были отправлены.
Есть ли лучший способ управлять транзакциями в этой ситуации? Можно ли как-то решить без возможности проверить в будущем, был ли наш внешний вызов успешным или нет? (например, я могу проверить все прошлые транзакции в блокчейне)