2PC распределял транзакции по множеству микросервисов?

Я прочитал некоторую информацию о распределенных транзакциях 2 Phase Commit/XA и о том, как JTA поддерживает их. Кажется, что есть много менеджеров ресурсов - RM (например, RDBMS или JMS) и один экземпляр TransactionManager (TM), который управляет глобальными транзакциями во многих RM.

Я знаю, что лучше использовать шаблон Saga, но все же интересно подумать:

  1. Дают ли распределенные транзакции 2PC/XA возможность проведения транзакций со многими RM только из одного приложения и одного TM?
  2. Если нет - как использовать распределенные транзакции 2PC/XA между многими микросервисами, чтобы обеспечить возможность использования 2PC, если каждый микросервис имеет доступ только к своей базе данных? буду рад увидеть пример
  3. Нужно ли нам использовать службу TransactionManager как отдельную микрослужбу, чтобы обеспечить 2PC между многими микрослужбами?

UPD: в мире JTA TransactionManager не предоставляет REST API для управления транзакциями между микросервисами. LIXA предоставляет эту возможность. Статья с примерами в дополнение к ответам :)

что вы подразумеваете под "много RM только из одного сервиса и одного TM"?

WebServer 23.12.2020 02:02

Мое понимание 2PC/XA: если у нас есть одно монолитное приложение с двумя разными подключениями к базе данных - мне ясно, как использовать TransactionManager, который будет частью этого приложения, чтобы мы могли делегировать управление распределенными транзакциями по * многим базам данных / JMS. системы в TransactionManager. Но я не могу представить, как управлять несколькими базами данных в разных микросервисах, где мы используем шаблон базы данных для каждого сервиса, и каждый сервис имеет доступ только к своей БД. Как в этом случае делать распределенные транзакции 2PC/XA?

Dmitriy Mishenyov 23.12.2020 09:00
Полный курс Java для разработчиков веб-сайтов и приложений
Полный курс Java для разработчиков веб-сайтов и приложений
Получите сертификат Java Web и Application Developer, используя наш курс.
Что такое управление транзакциями JDBC и как оно используется для поддержания согласованности данных?
Что такое управление транзакциями JDBC и как оно используется для поддержания согласованности данных?
Управление транзакциями JDBC - это мощная функция, которая позволяет рассматривать группу операций с базой данных как единую единицу работы. Оно...
Выполнение HTTP-запроса с помощью Spring WebClient: GET
Выполнение HTTP-запроса с помощью Spring WebClient: GET
WebClient - это реактивный веб-клиент, представленный в Spring 5. Это реактивное, неблокирующее решение, работающее по протоколу HTTP/1.1.
Gradle за прокси-сервером
Gradle за прокси-сервером
Создайте проект Gradle под сетевым прокси.
6
2
1 149
1
Перейти к ответу Данный вопрос помечен как решенный

Ответы 1

Ответ принят как подходящий

В микросервисах транзакция должна выполняться путем предоставления API-интерфейсов Prepare & Commit. Также должен быть менеджер транзакций для координации транзакций.

Например, предположим, что существует 2 разных банка и 100 долларов США со счета_A в банке 1 должны быть переведены на счет_B в банке 2. Кроме того, предположим, что орган центрального банка несет ответственность за завершение транзакции. способ работы 2PC выглядит следующим образом:

  1. Центральный банковский орган (менеджер транзакций) получит запрос на перевод 100 долларов США со счета_A из банка1 на счет_B из банка2.

    a. https://CentralBank/Transaction?from=Bank1-Account_A&to=Bank2-Account_B&amount=100
    
  2. Центральный банк сохранит это в своей базе данных транзакций с некоторым идентификатором транзакции = 123. Также он вернет идентификатор транзакции для вызова, чтобы позже он мог вызвать, чтобы получить статус транзакции.

    a. add transaction 123 in database with status open
    
  3. PREPARE PHASE Менеджер транзакций выдаст следующие RPC-команды:

    a. https://Bank1/Prepare?Account=Account_A&money=100&action=subtract&transactionid=123
    b. https://Bank2/Prepare?Account=Account_B&money=100&action=add&transactionid=123
    
  4. ЭТАП СОВЕРШЕНИЯ Когда он получает успешный ответ на оба вызова на этапе подготовки, он переходит к этапу фиксации, где выдает следующие команды:

    a. move transaction 123 to committed state
    b. https://Bank1/Commit?transactionid=123
    c. https://Bank2/Commit?transactionid=123
    
  5. Как только он получит успешный ответ на оба вызова на этапе фиксации, центральный банк может перевести транзакцию в состояние «Завершено» (необязательно).

  6. Если какой-либо из шагов фазы PREPARE или COMMIT завершается неудачей, координатор транзакции прерывает транзакцию, выдавая следующие команды:

    a. move transaction 123 to Failed state
    b. https://Bank1/Rollback?transactionid=123
    c. https://Bank2/Rollback?transactionid=123
    

Вышеупомянутая проблема — это форма фиксации Distributed Atomic, и 2PC — один из способов сделать это. Также обратите внимание, что у 2PC есть много недостатков, например, что произойдет, если после фазы ПОДГОТОВКИ произойдет сбой центрального банка. Кроме того, что делать, если шаг 4.c терпит неудачу, а шаг 4.b завершается успешно и т. д. Обсуждение этих вопросов само по себе является очень обширным исследованием, но о нем все же следует знать. Несмотря на множество недостатков, 2PC широко используется из-за своей простоты.


Нужно ли нам использовать службу TransactionManager как отдельную микрослужбу, чтобы обеспечить 2PC между многими микрослужбами?

Теоретически нет. Если вы внимательно наблюдаете, любой из банков (Банк1 или Банк2) также может выступать в качестве менеджера транзакций (ему просто нужна отдельная таблица базы данных Транзакция), но практически много времени он хранится как отдельный микросервис.

Другие вопросы по теме