如何在提交时使用JTA确认JMS消息?

时间:2013-01-10 17:09:23

标签: java jms jta bitronix

我在使用JTA,两阶段提交,JMS和JDBC事务。这个想法是(简而言之)

  1. 在队列中收到消息
  2. 执行一些数据库操作
  3. 在数据库操作成功时确认消息
  4. 所以我得到XAQueueConnectionFactory,创建XAQueueSession,从会话中创建一个接收器并设置一个消息监听器。

    在监听器内部,在onMessage方法中,我开始我的用户事务,执行jdbc内容并提交事务或执行回滚,如果出现问题。现在,我希望(也就是“希望”)在用户事务提交时确认消息。

    但是这种情况不会发生,消息仍在队列中并一次又一次地重新传递。

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

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

3 个答案:

答案 0 :(得分:2)

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

答案 1 :(得分:0)

当你在监听器中说你开始你的用户事务时,这似乎暗示你正在使用Bean管理事务(BMT)。有这么好的理由吗?

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

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

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

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

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

答案 2 :(得分:0)

我认为在XA中你不能使用交易会话。