我有一个非常简单的场景,涉及 数据库JMS 在应用程序服务器(玻璃鱼)中。场景很简单:

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. 

问题是有时 消息是在插入之前传递的 在数据库中。如果我们考虑2阶段提交协议,这实际上是可以理解的:

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文档中。我们可以假设它们会根据使用时根据顺序入伍,但是使用JPA等ORM,很难知道何时刷新数据以及何时真正使用了数据库连接。任何想法?

有帮助吗?

解决方案

您正在体验经典的XA 2-PC比赛条件。它确实发生在生产环境中。

我想到三件事。

  1. JDBC是非XA资源的最后一个代理优化。(丢失恢复语义)
  2. 有JMS的时间。 (故意失去实时)
  3. 构建重试JDBC代码。 (对功能的影响最小)

WebLogic具有此LLR优化避免了此问题,并为您提供所有XA保证。

许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top