Собственно, как организовать транзакционную передачу данных по сети?
Банальный пример - операция пополнения счета.
Сервис А сообщает сервису Б, что пользователь на стороне А пополнил счет. И в этот момент, при успешной операции на Б, по сети теряется ответ для А об успешности операции. Возникает ситуация, что А попытается повторно пополнить счет, т.к. ответ не был получен.
Пока вижу такой вариант, начать операцию по передаче данных, открыв транзакцию с таймаутом на Б.
При удачном ответе от Б к А, сервис А отправляет запрос на закрытие транзакции Б по данной операции.
При всех неудачных операциях, транзакция просто закрывается по таймауту.
Сервис А сообщает Б, что пользователь пополнил на стороне А счёт, номер этой транзакции такой-то.
Сервис Б в ответ сообщает, что транзакция обработана, ну или о какой-то ошибке в строгом формате.
Если сервис А не получает такое сообщение, то через некоторое время отправляет сообщение повторно с тем же самым номером транзакции. Если сервис Б находит такую транзакцию у себя - отвечает, что событие уже обработано. Если не находит - обрабатывает штатно как новую транзакцию.
Сервис А ставит операции статус "выполнено" только после получения ответа от Б, пока ответа нет - служебный статус "обрабатывается"
Вполне. Могут быть вариации, но суть схожа. Например, система А отправляет событие, система Б генерирует id транзакции. Следом система Б обращается к системе А с вопросом: вот по такой-то транзакции запрос выполнять? Соответственно, А может удивиться "не знаю такую транзакцию"
Есть огромный бонус в том, что архитектурно предусмотрена суровая реальность - что делать, если система Б случайно упала. Ничего не делать, как поднимется - так и получит штатно все пропущенные сообщения.
Но это всё-таки сценарии не атомарные. Некоторое небольшое время Б может быть закоммичено, а А - ещё в процессе или наоборот. Eventual consistency т.е.
Если нужно именно закоммитить распределённую транзакцию - то посмотрите в сторону двуфазного коммита. Помнится, там ворох своих граблей.
Транзакция проходит на стороне А (платежный агрегатор. пример).
После проведения операции у себя, он шлет данные к Б.
Если Б не отвечает, то А ставит отправку данных к Б в очередь и повторяет данную операцию до тех пор, пока не будет получен Ок от Б.
С чего это? Если данные будут отправлены уже в сторону Б и Б их принял. Вопрос только в том, какую проверку проводить со стороны Б и что отдавать А, чтобы А считал что операция обмена с Б прошла успешно.
Вам алгоритм нужен или прям реализация?
Алгоритм простой. Когда А отсылает данные к Б, то Б должен принять их, проверить,записать к себе и отдать Ок статус к А. А проверяет есть ли в ответ Ок статус и помечает у себя как успешную операцию.
Как это Б не сможет проверить, если А уже законнектился к нему и отослал данные после восстановления связи??? Или Вы рассматриваете такой момент, что во время той 1мс, когда будет осуществляться прием-отправка от А к Б и обратно, произойдет разрыв?
Вам уже ниже написали еще реализацию обмена, там двойная проверка и идентификаторы, что придаст Вам уверенности в том, что записи об операциях будут отправлены с А на Б, проверена доставка с А на Б, и отправлен отчет к А стороны Б об успешной записи.
Сначала А посылает запрос на создание пустой (непогашенной) транзакции на Б.
"Б" возвращает в ответе идентификатор транзакции.
"А" посылает запрос на оплату транзакции с полученным идентификатором.
В случае, если ответ от "Б" не дошел до "А", а операция совершилась, то при повторной попытке оплатить транзакцию "Б" ответит ошибкой "уже оплачно".
Также такой механизм дает возможность для "А" делать запрос о статусе транзакции на "Б".