在提交事务之前传送 JMS 消息

发布于 2024-08-24 10:07:53 字数 1033 浏览 8 评论 0原文

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

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(1

马蹄踏│碎落叶 2024-08-31 10:07:53

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

我想到了三件事。

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

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.

  1. Last agent optimization where JDBC is the non-XA resource.(Lose recovery semantics)
  2. Have JMS Time-To-Deliver. (Deliberately Lose real time)
  3. Build retries into JDBC code. (Least effect on functionality)

Weblogic has this LLR optimization avoids this problem and gives you all XA guarantees.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文