Взгляд на принцип транзакции 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.