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

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

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

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

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


person Dmitriy Mishenyov    schedule 20.12.2020    source источник
comment
Что вы подразумеваете под множеством RM только из одной службы и одного TM?   -  person WebServer    schedule 23.12.2020
comment
Мое понимание 2PC / XA: если у нас есть одно монолитное приложение с двумя разными подключениями к базе данных - мне ясно, как использовать TransactionManager, который будет частью этого приложения, чтобы мы могли делегировать управление распределенными транзакциями между * многими базы данных / системы JMS до TransactionManager. Но я не могу себе представить, как управлять несколькими базами данных в разных микросервисах, где мы используем базу данных для каждого шаблона службы, и каждая служба имеет доступ только к своей БД. Как в этом случае выполнять распределенные транзакции 2PC / XA?   -  person Dmitriy Mishenyov    schedule 23.12.2020


Ответы (1)


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

Например, предположим, что существует 2 разных банка, и 100 долларов США из Account_A в Bank1 необходимо перевести на Account_B из Bank2. Кроме того, предположим, что центральный банк несет ответственность за завершение транзакции, как будет работать 2PC:

  1. Орган центрального банка (менеджер транзакций) получит запрос на перевод 100 долларов с Account_A из Bank1 на Account_B из Bank2.

    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. ПОДГОТОВИТЬ ЭТАП Менеджер транзакций выдаст следующие команды 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
    

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


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

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

person WebServer    schedule 23.12.2020
comment
Спасибо за ответ, мне это помогло! - person Dmitriy Mishenyov; 24.12.2020