Как создать глобальную распределенную транзакцию (ни одна база данных)? Может ли JTA использовать для транзакции db?

Я думаю, что это довольно распространенный вопрос: как разместить мою бизнес-логику в глобальной транзакции в среде распределенных систем? Приведите пример, у меня есть TaskA, содержащий пары подзадач:

TaskA {subtask1, subtask2, subtask3...}

каждая из этих подзадач может выполняться на локальном компьютере или удаленном, надеюсь, TaskA выполняется атомным способом (успех или неудача) посредством транзакции. Каждая подзадача имеет функцию отката, как только TaskA считает, что операция завершается неудачно (поскольку одна из подзадач не работает), она вызывает каждую функцию отката подзадач. В противном случае TaskA совершает всю транзакцию.

Чтобы сделать это, я следую за шаблоном транзакции "Audit trial", чтобы иметь запись для каждой подзадачи, поэтому TaskA может узнать результаты работы подзадач, а затем решить откат или фиксацию. Это звучит просто, но сложная часть заключается в том, как связать каждую подзадачу с глобальной транзакцией?

Когда TaskA начинается, он запускает глобальную транзакцию о том, какая подзадача ничего не знает. Чтобы подзадача знала об этом, я должен передать контекст транзакции для каждого вызова подзадачи. Это действительно ужасно! Моя подзадача может либо выполняться в новом потоке, либо выполнять на удаленном компьютере, отправив сообщение через посредника AMQP, трудно консолидировать способ распространения контекста.

Я сделал несколько исследований, таких как "Шаблоны транзакций - сборка четырех связанных с транзакциями шаблонов", "Проверенные транзакции в среде переноса асинхронных сообщений", ни одна из них не решила мою проблему. Они либо не имеют практического примера, либо не решают проблему распространения контекста.

Интересно, как люди это решают? так как такая сделка должна быть распространена в корпоративном программном обеспечении.

Является ли X/Open XA только решением для этого? Может ли JTA помочь здесь (я не рассматривал JTA, поскольку большинство материалов для нее связано с транзакцией базы данных, и я использую Spring, я не хочу привлекать другой сервер приложений Java EE в свое программное обеспечение).

Может ли какой-нибудь эксперт поделиться со мной некоторыми мыслями? спасибо.

Заключение

Аржан и Мартин дали действительно хорошие ответы, спасибо. Наконец, я не пошел таким путем. После большего исследования я выбрал еще один шаблон " CheckPoint" 1.

В моем требовании я обнаружил, что намерен "Audit Trial Transaction Pattern" - узнать, на каком уровне выполнялась операция, если он не удался, я могу перезапустить его в неудавшемся месте после перезагрузки некоторого контекста. На самом деле это не транзакция, она не откат других успешных шагов после сбоя. Это суть шаблона CheckPoint. Однако изучение материалов распределенной транзакции заставляет меня узнать много интересного. Кроме того, о чем говорили Арьян и Мартин. Я также предлагаю людям, копающимся в этой области, взглянуть на CORBA, который является широко известным протоколом для распределенной системы.

Ответ 1

Вы правы, вам нужна поддержка двухфазной фиксации благодаря менеджеру транзакций XA, предоставляемому API JTA.

Насколько я знаю, Spring не предоставляет реализацию самого менеджера транзакций. JtaTransactionManager делегирует только существующую реализацию, обычно предоставляемую из реализаций JavaEE.

Поэтому вам нужно будет подключить реализацию JTA в Spring, чтобы получить эффективную работу. Вот несколько предложений:

Затем вам нужно будет реализовать диспетчер ресурсов для поддержки двухфазной фиксации. В мирах JavaEE он состоит из адаптера ресурсов, упакованного как архив RAR. В зависимости от типа ресурса для чтения/реализации должны читаться следующие аспекты:

В качестве примеров я рекомендую посмотреть на реализацию классических проблем с транзакциями с файлами:

Ответ 2

Если вы хотите написать свой собственный транзакционный ресурс, вам действительно нужно реализовать XAResource и позволить ему присоединяться к текущей транзакции, обрабатывать и обрабатывать запросы от диспетчера транзакций и т.д.

Источники данных являются наиболее известными транзакционными ресурсами, но, как уже упоминалось, они не единственные. Вы уже упомянули поставщиков JMS. Различные решения кэширования (например, Infinispan) также являются транзакционными ресурсами.

Реализация XAResources и работа с частью более низкого уровня API JTA и JTS (Java Transaction Service) с еще более низким уровнем обслуживания не является задачей для слабонервных. API может быть архаичным, и весь процесс практически не документирован.

Причина в том, что обычные корпоративные приложения, создающие собственные транзакционные ресурсы, крайне редки. Весь смысл быть транзакционным - сделать действие, которое является атомарным для внешнего наблюдателя.

Чтобы быть заметным в подавляющем большинстве случаев, эффекты действия присутствуют в базе данных. Почти каждый источник данных уже является транзакционным, так что прецедент полностью закрыт.

Другим наблюдаемым эффектом является то, было ли отправлено сообщение или нет, и это также полностью покрывается существующими решениями обмена сообщениями.

Наконец, обновление (по всей кластеру) карты памяти является еще одним наблюдаемым эффектом, который также покрывается основными поставщиками кэшей.

Там есть остаточный спрос на транзакционные эффекты при работе с внешними корпоративными информационными системами (EIS), и, как правило, поставщики таких систем предоставляют соединители, поддерживающие транзакции.

Дрожь вариантов использования, которые остаются, настолько мала, что, по-видимому, никто никогда не беспокоился много писать об этом. Есть некоторые блоги, которые охватывают некоторые из основ, но многое останется для ваших собственных экспериментов.

Попробуйте убедиться сами, если вам действительно нужно идти по этой дороге, и если ваша потребность не может быть удовлетворена одним из существующих транзакционных ресурсов.

Ответ 3

Вы можете сделать следующее (похоже на вашу стратегию контрольной точки):

  • TaskA выполняется в (локальной) транзакции JTA и пытается зарезервировать необходимые ресурсы до того, как он делегирует ваши подзадачи

  • Вызовы подзадачи выполняются через JMS/XA: если шаг 1 терпит неудачу, никакая подзадача никогда не будет запущена, и если будет выполнен шаг 1, то вызовы JMS будут приниматься в каждой подзадаче

  • Подзадачи (re) пытаются обработать свое сообщение о вызове с помощью набора ограничений пересылки JMS max (см. ваши документы поставщика JMS о том, как это сделать)

  • Настройте "мертвую буквенную очередь" для любых сбоев в 3.

Это работает, предполагая, что:

-выполнение на шаге 3 имеет смысл

- требуется несколько человеческих вмешательств, необходимых для сообщений в очереди мертвых букв

Если это неприемлемо, существует также TCC: http://www.atomikos.com/Main/DownloadWhitepapers?article=TccForRestApi.pdf - это можно рассматривать как шаблон резервирования для служб REST.

Надеюсь, что это поможет

Гай

http://www.atomikos.com