我在使用JTA,两阶段提交,JMS和JDBC事务。这个想法是(简而言之)
所以我得到XAQueueConnectionFactory
,创建XAQueueSession
,从会话中创建一个接收器并设置一个消息监听器。
在监听器内部,在onMessage
方法中,我开始我的用户事务,执行jdbc内容并提交事务或执行回滚,如果出现问题。现在,我希望(也就是“希望”)在用户事务提交时确认消息。
但是这种情况不会发生,消息仍在队列中并一次又一次地重新传递。
我错过了什么?我仔细检查了会话,确认模式确实是“SESSION_TRANSACTED
”,getTransacted
返回true。
我没有Java EE容器,没有spring,没有消息驱动的bean。我使用独立的JTA bitronix。
答案 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中你不能使用交易会话。