Comments 20
Покажите код действительно рабочего надёжного решения энтерпрайзного уровня, а не hello-world.
По-идее, сагу тоже можно делать распределённой. Собственно, я так всегда и делал, не зная что у меня получается распределённая сага :-)
По сути, другого выбора, кроме саги, в распределенных сервисах просто нет. Это может быть как формальная сага, так и сага по сути. В противном случае получите неконсистентные данные.
Нужно всегда отдавать себе отчет, какие свойства проектируемой системы критичны, и какие особенности автоматизируемых бизнес-процессов будут сложны в своей имплементации. Ибо есть очень интересное фундаментальное ограничение, вытекающее из теории информации — нельзя просто сделать сложное. Автоматизация сложного бизнес процесса будет как минимум не проще его самого.
Если нужны когерентные источники корректно-многосвязных данных — то без ACID будет очень сложно. С другой стороны, ACID дается очень дорого. Если из обычной БД откусить ACID, то она будет стрелять, как no-sql key-value пулемет. Поэтому, если когерентность вам не нужна, и транзакционность тоже не очень важна, и модель данных несложная — можно и распилить.
У Вас сообщение в event bus шине осталось. Она считается априори надежной. Теоретически можно всегда сходить в сервис, DONE которого потерялся, и запросить его повторно. Вопрос в том, что это совсем какая-то аварийная ситуация. И вероятно, что у Вас проблемы существенно более серьёзные, чем отсутствие единственного DONE
Если я Вас не понял — поясните, пожалуйста, свою мысль более развёрнуто
Теоретически можно всегда сходить в сервис, DONE которого потерялся, и запросить его повторно.Я имею в виду случай когда второй DONE не потерялся, а вернулся с FAIL-ом.
Понял, Вы про 2PC с transaction coordinator (а не про сам атомарный 2PC внутри микросервиса). Тогда он просто откатывает все транзакции, которые идут в микросервисы....
1. Оба PREPARE прошли и вернули DONE. В этом момент изменение еще никто не видит из вне.
2. COMMITE первого сервиса прошел, а второй нет. В этой ситуации сторонни наблюдатель видит изменения в первом микросервисе, но не видит во втором. Я пока не вижу тут из чего вытекает общая атомарность общей транзакции. Можете пояснить пожалуйста?
У Вас атомарность обеспечивается тем, что внешний наблюдатель не ходит напрямую в оконечные микросервисы. Они ходят через фасад. Ну, и в конечном счете все равно надо писать так сервисы, чтобы изменение состояние в одном микросервисе (если все-таки кто-то ходит в них напрямую) не ломает всю систему целиком (ну, была заявка на заказ и резерв на товары — заказ сломался, снимаем заявку на заказ и резерв)
Давайте абстрактно, без всяких заказов, резервов и т.д. Допустим я оркестратор, у меня есть две БД и я пытаюсь транзакционно записать две записи в одну и другую базу. Транзакционно, это значит что они либо должны обе появиться и в одной БД и в другой, либо не появиться вовсе. Делаю PREPARE записи в одной БД — ок, делаю PREPARE записи в другой БД — ок. Пока что, если сделать параллельный запрос то записи не видны ни там ни там. Теперь я делаю DONE в первую БД — теперь запись появилась в одной БД, но второй записи еще нет во второй БД. Где тут транзакция? Из объяснения в статье этого не видно.
Обработка распределенных транзакций в микросервисной архитектуре