在提交事务之前传递

在提交事务之前传递

本文介绍了在提交事务之前传递 JMS 消息的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我有一个非常简单的场景,涉及应用服务器(Glassfish)中的数据库JMS.场景非常简单:

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.

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

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".

我的问题是:

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

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

Here are a bit more details about my understanding of the problem:

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

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.

我发现在 JTA、JCA 和 JPA 规范和 Glassfish 文档中都没有办法控制分布式事务中参与者的顺序.我们可以假设它们会按照使用的顺序在分布式事务中登记,但是对于像 JPA 这样的 ORM,很难知道何时刷新数据以及何时真正使用数据库连接.有什么想法吗?

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?

推荐答案

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

You are experiencing the classic XA 2-PC race condition. It does happen in production environments.

我想到了 3 件事.

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

Weblogic 的 LLR 优化避免了这个问题,并为您提供所有 XA 保证.

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

这篇关于在提交事务之前传递 JMS 消息的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持!

08-04 06:56