Филипп Вагнер "Распределенные транзакции в условиях микросервисной архитектуры"/M2_TECH Scala Meetup
HTML-код
- Опубликовано: 28 сен 2023
- Филипп делится нюансами и способами организации распределённых транзакций в условиях микросервисной архитектуры на примере паттернов SAGA, Transactional outbox.
Полезные ссылки:
- zio-saga: github.com/VladKopanev/zio-saga
- cats-saga: github.com/VladKopanev/cats-saga
- transaction-outbox: github.com/gruelbox/transacti...
- Saga pattern: microservices.io/patterns/dat...
- Transactional Outbox pattern: microservices.io/patterns/dat...
Наш телеграм канал - t.me/techm2
Наш Хабр - habr.com/ru/companies/m2tech
Я б с такой фамилией на самолётах не летал
Шойгу Герасимов - где мои 'оркестраторы"?!!
В страну 404 самое то
Смотрю на первую каритинку с монолитом, все в одном месте транзакции из коробки, понятно как с ними работать. Потом делим это все на домены, получаем сетевые накладные расходы, теряем изоляцию и строгую согласованность, добавляем кафку, добавляем доп таблицы, добавляем message relay. Выглядит это сложно. Доклад хороший.
С монолитами тяжелее работать.
Накосячил в одном месте - не работает все.
Разделенные среды на домены там все просто и понятно.
Модули, библиотеки превентирующие нарушение изоляции модулей, обычный code review в конце концов и нет проблем с монолитом.
Но да, нужна культура и совесть разрабов (-> компетенции), распределенка таких проблем просто физически не допустит
Очень понятно и просто обьяснил довольно сложную тему!
RUclips нужна опция пропускать все “aaa..”
Наконец то хороший доклад где простыми словами рассказано о патерне Saga
супер, спасибо. До этого видео думал что saga, это transaction-outbox, то есть когда нам нужно атомарно положить в базу и отправить в очередь. Но оказывается это ток подзадача более общей задач распределенных транзакций))
Прекрасный доклад! Благодарю!
Очень интересный доклад. Оказывается, можно в одной транзакции бронировать в нескольких тормознутых внешних сервисах ;-))
При двухфакторной аутентификации можно запускать изменения данных в нескольких сервисах параллельно, и только коммитить синхронно. Не обязательно ждать ответа первого чтобы запустить коммит во втором.
Строгая связность флоу - тоже не очень хорошо, потому что у нас может быть динамический флоу, т.е. чеолвек условно может чекбоксами натыкивать что ему надо, и на основе этого нам нужные разные цепочки? Мы задолбаемся все хардкодить.
Получается по факту нам опять же нужен какой-то контроллер, который будет решать, какие события он в шину отправляет в рамках конкретного заказа. Надо ли там бронировать машину или нет, а может вместо машины там нужен трансфер. А с трансферами такая лабуда, что некоторые отели могут их предоставлять бесплатно при снятии дорого номера, некоторые за отдельную плату, а у каких-то такой услуги вообще не будет и надо привлекать третью сторону(такси) и т.д. Просто создать 1 флоу не выйдет.
А получается что в случае саги нам опять таки нужен какой-то координатор, потому что условный сервис бронирования машин не должен знать(а тем более решать) какое действие должно происходить следующим. Поэтому жаль, что не затронули Event sourcing.
Спасибо за доклад. Очень понятно.
thank you
Здравствуйте. Как обрабатывать такой кейс, когда например у саги 3-я по счету локальная транзакция не проходит, запускаются компенсационные транзакции на 1-м и 2-м шаге, и валится второй сервис и компенсационные действия на 2-ом и 1-ом шаге не выполняются?
Судя по презентации, докладчик не понимает что такое атомарность и согласованность. Например - атомарность, это когда несколько действий воспринимаются как одно. Что будет что после коммита первого сервиса какой-то сторонний сервис поменяет так данные что компенсирующая транзакция не сможет выполниться? Данные первого сервиса доступны (закоммичены) для сторонних сервисов в то времмя когда не закомиченны данные остальных сервисов? И где тут атомарность?
Я так и не понял что будет если откат уже не возможен в сервисе который завершил свою часть. Н-р на эти записи уже другая транзакция наложила свои изменения
по идее эти данные надо держать неизменными до подтверждения. Тут кажется уже не техническая реализация нужна, а бизнес реализация. Если клиент сделал бронь и не дождавшись завершения саги например её оплатил, то при откате первой саги надо сначала откатить вторую. Не знаю можно ли расширять сагу на ходу. В таком сценарии ничего страшного, оплата возвращается. Но распределенные транзакции выглядят как последний довод, когда других альтернатив уже нет
Я в восторге, вау 😙
А может пересмотреть границы микросервисов? Если к примеру выделить агрегат - направление путешествия, то можно в рамках него провести все требуемые бронирования в одной транзакции
почему Аурус стоит после Майбах?
8:35 здесь надо бы сказать, что компенсирующая транзакция тоже может не выполниться.
Доклад интересный, но вот разрешение видео бы побольше сделать. Сложно смотреть на 4К телевизоре.
А если в базах добавить еще одно логическое поле "подтверждено" и устанавливать там true если все транзакции прошли успешно. Клиенту в это время можно сообщать, что майбах выбран другим клиентом, но еще окончательно не забронирован. Можно его глянуть попозже.
ждали самую медленную, потом начали ждать все три последовательно. 100% быстрее)
Dirty read зачем-то какими-то обманутыми транзакциями обозвали
Вагнер уже и до Программирования дотянулся !
Узнаю Яндекс - все примеры исключительно на майбахах и аурусах
Он че вагнеровец
Разберитесь получше, что такое уровни изоляции транзакций, В сценарии названном у вас как false positive - названные уровни изоляции - вам не помогут. эта задача решается только блокировкой на БД или другом каком то общем разделяемом ресурсе.
В зависимости от уровней изоляции под капотом также используюся блокировки на затронутые строки. На примере pg:
* Для read committed - будет наложена блокировка на обновляемые строки и другие транзакции, меняющие те же строки, будут ждать пока транзакция, которая наложила блокировку, её отпустит (произойдет commit или rollback). Затем ожидающие транзакции перевыполнят запрос на обновления и первая из них снова наложит блокировку на записи.
* Для repeatable read - такой же процесс, но только блокировка накладывается на записи при их выборке через select
В примере с read committed тоже не должно возникнуть проблем, если запрос учитывает, что машина уже может быть не доступна (по флагу/статусу/кол-ву доступных машин), а не просто обновляет поле записи. Что-то вроде: update foo set availableCount = availableCount - 1 where id = 1 and availableCount > 0.