Доставка сообщения JMS до совершения транзакции - PullRequest
20 голосов
/ 10 марта 2010

У меня очень простой сценарий, включающий базу данных и JMS на сервере приложений (Glassfish). Сценарий очень прост:

1. an EJB inserts a row in the database and sends a message.
2. when the message is delivered with an MDB, the row is read and updated. 

Проблема в том, что иногда сообщение доставляется до того, как вставка была зафиксирована в базе данных. Это на самом деле понятно, если мы рассмотрим протокол двухфазной фиксации:

1. prepare JMS
2. prepare database
3. commit JMS
4. ( tiny little gap where message can be delivered before insert has been committed)
5. commit database

Я обсуждал эту проблему с другими , но ответ всегда был: «Странно, это должно работать из коробки» .

Мои вопросы:

  • Как это могло работать из коробки?
  • Мой сценарий звучит довольно просто, почему нет людей с подобными проблемами?
  • Я что-то не так делаю? Есть ли способ решить эту проблему правильно?

Вот немного больше информации о моем понимании проблемы:

Эта проблема времени существует, только если участник обрабатывается в этом порядке. Если 2PC обрабатывает участников в обратном порядке (сначала база данных, а затем брокер сообщений), это должно быть хорошо. Проблема возникала случайным образом, но полностью воспроизводилась.

Я не нашел способа контролировать порядок участников распределенных транзакций в спецификациях JTA, JCA и JPA, ни в документации Glassfish. Можно предположить, что они будут зачислены в распределенную транзакцию в соответствии с порядком их использования, но при использовании ORM, такого как JPA, трудно определить, когда данные сбрасываются и когда соединение с базой данных действительно используется. Есть идеи?

1 Ответ

11 голосов
/ 29 марта 2010

Вы испытываете классическое состояние гонки XA 2-PC. Это происходит в производственных условиях.

На ум приходят 3 вещи.

  1. Последняя оптимизация агента, где JDBC - не-XA-ресурс. (Потерять семантику восстановления)
  2. Имейте JMS Time-To Deliver. (Умышленно проигрывать в реальном времени)
  3. Сборка повторяется в коде JDBC. (Наименьшее влияние на функциональность)

Weblogic имеет эту оптимизацию LLR, позволяет избежать этой проблемы и дает вам все гарантии XA.

...