2

我在 JTA、两阶段提交、JMS 和 JDBC 事务中苦苦挣扎。这个想法是(简而言之)

  1. 在队列中接收消息
  2. 执行一些数据库操作
  3. 确认消息,当数据库操作成功时

所以我得到了XAQueueConnectionFactory,创建了XAQueueSession,从会话中创建了一个接收器并设置了一个消息监听器。

在侦听器内部,在onMessage方法中,我开始我的用户事务,执行 jdbc 内容并提交事务或执行回滚,如果出现问题。现在我预计(又名“希望”)当用户事务提交时消息会被确认。

但这并没有发生,消息仍在队列中,并且一次又一次地重新传递。

我错过了什么?我仔细检查了会话,确认模式确实是“ SESSION_TRANSACTED”并getTransacted返回 true。

我没有 Java EE 容器,没有 spring,没有消息驱动 bean。我使用独立的 JTA bitronix。

4

3 回答 3

2

您实际上并不需要 XA。只需遵循您的算法:接收消息,执行数据库操作,然后确认消息......从字面上看,这就是解决方案。(而不是事务会话,您可能只需要显式选择 CLIENT_ACKNOWLEDGE。)如果您的应用程序在执行数据库操作时失败,请不要确认 JMS 消息,它将被重新传递。如果您的应用程序在 DB txn 之后和 ack 之前失败,则消息将被重新传递 - 但您可以检测到这一点(消息上的重新传递标志将设置为 true),您可以决定是否重新处理消息,基于数据库的状态。

于 2013-08-31T07:55:20.767 回答
0

当您说在侦听器内部开始您的用户事务时,这似乎暗示您正在使用 Bean Managed Transaction (BMT)。这样做有充分的理由吗?

如果您使用容器管理事务 (CMT),那么您想要的将是免费的。

据我记得,BMT 是不可能的,因为 UserTransaction 不会参与,也无法参与为消息创建的事务。但是您可能需要仔细检查 Java EE 规范。

编辑:对不起,我意识到你没有使用 Java EE 容器为时已晚。

您确定您在侦听器内启动的用户事务是为消息启动的事务的一部分吗?您似乎为数据库工作启动了一个独立的事务。

如果不使用容器,谁提供 JMS 实现,即 XAQueueConnectionFactory 等?

于 2013-03-04T10:51:10.587 回答
0

我认为对于 XA,您不应该使用事务处理会话。

于 2015-05-20T08:18:38.040 回答