Взгляд на принцип транзакции XA
XA — это спецификация распределенных транзакций, предложенная организацией X/Open. Модель X/Open Distributed Transaction Processing (DTP) состоит из трех программных компонентов:
- Прикладная программа (AP) определяет границы транзакции и указывает действия, составляющие транзакцию.
- Менеджеры ресурсов (RM, такие как базы данных или системы доступа к файлам) обеспечивают доступ к общим ресурсам.
- Отдельный компонент, называемый диспетчером транзакций (TM), присваивает идентификаторы транзакциям, отслеживает их ход и берет на себя ответственность за завершение транзакций и устранение сбоев.
На следующем рисунке показаны интерфейсы, определенные моделью X/Open DTP.
XA делится на две фазы.
- Фаза 1 (подготовка): все участвующие RM готовятся к выполнению своих транзакций и блокируют необходимые ресурсы. Когда каждый участник готов, он сообщает ТМ.
- Фаза 2 (фиксация/откат): когда диспетчер транзакций (TM) получает, что все участники (RM) готовы, он отправляет команды фиксации всем участникам. В противном случае он отправляет команды отката всем участникам.
В настоящее время почти все популярные базы данных поддерживают транзакции XA, включая Mysql, Oracle, SqlServer и Postgres.
ХА в Mysql
Давайте посмотрим, как база данных Mysql поддерживает XA с помощью кода ниже:
Бизнес-сценарий
Межбанковский перевод — это типичный сценарий распределенной транзакции, когда А должен перевести деньги через банк в Б. И снятие, и депозит могут быть успешными или неудачными, и требуется, чтобы сумма баланса А и Б не менялась. после завершения передачи, независимо от любых возникающих ошибок.
Реализация распределенной транзакции XA
Распределенные транзакции XA могут решить вышеуказанную бизнес-проблему. В данной статье представлено решение на базе dtm-labs/dtm. DTM — это популярная платформа распределенных транзакций, которая поддерживает шаблоны XA, Saga, OutBox и TCC.
На следующем рисунке показана успешная глобальная транзакция:
Код для его реализации в Go довольно прост:
Приведенный выше код сначала регистрирует глобальную транзакцию XA, а затем вызывает две подтранзакции: TransOut
, TransIn
. После успешного выполнения подтранзакций глобальная транзакция XA фиксируется в DTM. DTM получает подтверждение глобальной транзакции XA, затем вызывает XA commit
всех подтранзакций и, наконец, изменяет статус глобальной транзакции на успешный.
Примеры кода на других языках можно найти здесь: SDK
Запустить его
Вы можете запустить приведенный выше пример, выполнив следующие команды.
Запустить DTM
git clone https://github.com/dtm-labs/dtm && cd dtm
go run main.go
Пример запуска
git clone https://github.com/dtm-labs/dtm-examples && cd dtm-examples
go run main.go http_xa
Откат после сбоя
Если какая-либо prepare
операция завершится неудачно, DTM вызовет XA rollback
каждой подтранзакции для отката и, наконец, изменит статус глобальной транзакции на сбой.
Давайте передадим TransInResult="FAILURE"
в полезной нагрузке запроса XaFireRequest, чтобы вызвать сбой.
req := &busi.TransReq{Amount: 30, TransInResult: "FAILURE"}
Временная диаграмма отказа выглядит следующим образом:
Уведомления
- Команда второй фазы также отправляется в API
BusiAPI+"/TransOutXa"
, и внутри этой службыdtmcli.XaLocalTransaction
автоматически вызываетXA commit
|XA rollback
. Таким образом, тело запроса равно нулю, и операции с телом синтаксического анализа, такие как предыдущаяreqFrom
, должны быть помещены внутрьXaLocalTransaction
. В противном случае разбор тела приведет к ошибкам.
Неудача ТМ
Сложность двухэтапной фиксации связана со всеми возможными сценариями отказа. Самый неприятный сбой происходит после того, как участник подтвердил и подготовился, и до того, как он получил решение, например, сбой координатора.
Наше решение этой проблемы довольно простое и надежное. Поскольку большинство поставщиков облачных услуг предоставляют базы данных с высокой доступностью, мы можем хранить ход выполнения подтранзакций в этих базах данных и запускать несколько экземпляров TM. Каждый экземпляр будет опрашивать приостановленные транзакции и продолжать их обработку.
Поставщик облачных услуг позаботится об отказе базы данных и может использовать Paxos/Raft для надежного выбора работоспособного экземпляра.
Преимущества и недостатки
По сравнению с другими шаблонами, такими как SAGA и TCC, преимущества глобальных транзакций XA:
- Просто и понятно
- Автоматический откат бизнеса, не нужно прописывать компенсацию вручную
К недостаткам ХА относятся:
- Нужна транзакция XA из базовой базы данных
- Данные блокируются с момента изменения данных до фиксации, что намного дольше, чем в других шаблонах. Это не подходит для высокопараллельного бизнеса.
Заключение
В этой статье представлен основной принцип транзакции XA и представлен ее практический пример. Читатели могут легко последовать этому примеру и заняться собственным бизнесом.
Добро пожаловать на github.com/dtm-labs/dtm. Это специальный проект, призванный упростить распределенные транзакции в микросервисах. Он поддерживает несколько языков и шаблонов, таких как двухфазное сообщение, Saga, TCC и XA.