我有一个非常简单的场景,涉及database and a 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
我讨论过这个问题和其他人 http://forums.java.net/jive/message.jspa?messageID=351867,但答案始终是:“奇怪,它应该开箱即用”.
我的问题是:
- 它如何开箱即用?
- 我的情况听起来很简单,为什么没有更多人遇到类似的问题呢?
- 难道我做错了什么?有没有办法正确解决这个问题?
以下是我对这个问题的理解的更多细节:
仅当参与者按此顺序处理时,才会存在此时间问题。如果 2PC 以相反的顺序对待参与者(首先是数据库,然后是消息代理),那应该没问题。该问题是随机发生的,但完全可以重现。
我在 JTA、JCA 和 JPA 规范中以及 Glassfish 文档中都找不到控制分布式事务参与者顺序的方法。我们可以假设它们会按照使用的顺序加入到分布式事务中,但是对于像 JPA 这样的 ORM,很难知道数据何时刷新以及数据库连接何时真正使用。任何想法?
您正在体验经典的 XA 2-PC 竞赛条件。它确实发生在生产环境中。
我想到了三件事。
- 最后的代理优化,其中 JDBC 是非 XA 资源。(丢失恢复语义)
- 有 JMS 交付时间。 (故意损失实时时间)
- 将重试构建到 JDBC 代码中。 (对功能影响最小)
Weblogic 的 LLR 优化避免了这个问题,并为您提供所有 XA 保证。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)