在提交事务之前传送 JMS 消息
我有一个非常简单的场景,涉及应用程序服务器(Glassfish)中的数据库和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.
问题在于有时消息是在数据库中提交插入之前传递的。如果我们考虑两阶段提交协议,这实际上是可以理解的:
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,很难知道数据何时被刷新以及数据库连接何时真正被使用。有什么想法吗?
I have a very simple scenario involving a database and a JMS in an application server (Glassfish). The scenario is dead simple:
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.
The problem is that sometimes the message is delivered before the insert has been committed in the database. This is actually understandable if we consider the 2 phase commit protocol:
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
I've discussed this problem with others, but the answer was always: "Strange, it should work out of the box".
My questions are then:
- How could it work out-of-the box?
- My scenario sounds fairly simple, why isn't there more people with similar troubles?
- Am I doing something wrong? Is there a way to solve this issue correctly?
Here are a bit more details about my understanding of the problem:
This timing issue exist only if the participant are treated in this order. If the 2PC treats the participants in the reverse order (database first then message broker) that should be fine. The problem was randomly happening but completely reproducible.
I found no way to control the order of the participants in the distributed transactions in the JTA, JCA and JPA specifications neither in the Glassfish documentation. We could assume they will be enlisted in the distributed transaction according to the order when they are used, but with an ORM such as JPA, it's difficult to know when the data are flushed and when the database connection is really used. Any idea?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
您正在体验经典的 XA 2-PC 竞赛条件。它确实发生在生产环境中。
我想到了三件事。
Weblogic 具有此 LLR 优化,可以避免此问题并为您提供所有 XA 保证。
You are experiencing the classic XA 2-PC race condition. It does happen in production environments.
There are 3 things coming to my mind.
Weblogic has this LLR optimization avoids this problem and gives you all XA guarantees.