database - 在提交事务之前传递 JMS 消息

标签 database jakarta-ee jms distributed-transactions 2phase-commit

我有一个非常简单的场景,涉及应用程序服务器 (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. 

问题是有时在数据库中提交插入之前传递消息。如果我们考虑 2 阶段提交协议(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

我已经讨论过这个问题with others ,但答案总是:“奇怪,它应该开箱即用”

我的问题是:

  • 它如何开箱即用?
  • 我的情况听起来很简单,为什么没有更多人遇到类似的麻烦?
  • 我做错了什么吗?有没有办法正确解决这个问题?

以下是我对问题的理解的更多细节:

仅当参与者按此顺序处理时,才会存在此时间问题。如果 2PC 以相反的顺序对待参与者(首先是数据库,然后是消息代理),那应该没问题。该问题是随机发生的,但完全可以重现。

在 Glassfish 文档中,我发现无法控制 JTA、JCA 和 JPA 规范中分布式事务参与者的顺序。我们可以假设它们将根据使用顺序在分布式事务中登记,但是使用 JPA 等 ORM,很难知道何时刷新数据以及何时真正使用数据库连接。有什么想法吗?

最佳答案

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

我想到了 3 件事。

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

Weblogic 有这个 LLR 优化避免了这个问题并给你所有的 XA 保证。

关于database - 在提交事务之前传递 JMS 消息,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/2418292/

相关文章:

java - 使用 JMS 进行简单聊天

mysql - 保持数据库连接是否更好?

java - JMS ObjectMessage 中保存的对象是否可以或是否与发布时的实例相同?

mysql - Q : How to set --set-gtid-purged=OFF as a default Export parameter in Mysql workbench?

java - Servlet异常: Method threw 'java.lang.NoClassDefFoundError'

java - 如何动态地将arraylist放入Hashmap中?

java - 如何避免 JMS 消息类的代码重复?

java - 在 Apache Camel 路由中间使用 JMS 能否保证交付?

database - 如何在 EclipseLink/JPA 中指定 @OneToMany 的基数

iPhone:在库文档中找不到 Sqlite 文件