2013-01-10 73 views
0

我使用JTA,两阶段提交,JMS和JDBC事务处理结构。这个想法是(简称)以如何在提交时使用JTA确认JMS消息?

  1. 收到一条消息在队列上
  2. 执行一些数据库操作
  3. 确认该消息,当数据库操作已经成功

所以我就XAQueueConnectionFactory,创建XAQueueSession,从会话创建接收器并设置消息监听器。

在侦听器内部,在onMessage方法中,我开始我的用户事务,执行jdbc的东西并提交事务或执行回滚,如果出现错误。现在,我期望(又称“希望”)在用户事务提交时确认该消息。

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

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

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

回答

0

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

如果您使用容器管理的交易(CMT),你想要什么免费。

据我所知,这是不可能与BMT,因为UserTransaction不会参与,并将不能参与为消息创建的事务。但是您可能需要仔细检查Java EE规范。

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

您确定在侦听器中启动的用户事务是为消息启动的事务的一部分吗?看来,你开始一个独立的数据库工作事务。

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

2

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

0

我觉得在XA你不会使用事务处理会话。