论坛首页 Java企业应用论坛

activemq 事务问题

浏览 6562 次
精华帖 (0) :: 良好帖 (0) :: 新手帖 (0) :: 隐藏帖 (0)
作者 正文
   发表时间:2012-01-31  

最近项目中用到activemq,有个事务问题搞得很烦。

activemq版本:5.4.2

spring版本:2.5.6

 

配置JMS连接工厂bean如下:
<!-- 配置JMS连接工厂 -->
 <bean id="fasp.nxch.connectionFactory" class="org.apache.activemq.spring.ActiveMQXAConnectionFactory">
  <property name="brokerURL" value="tcp://localhost:61616" />
 </bean>

 

配置目的地如下:
<!-- 接收消息的目的地(一个队列) -->
 <bean id="fasp.nxch.destinationForReceive" class="org.apache.activemq.command.ActiveMQQueue">
  <!-- 设置消息队列的名字 -->
  <constructor-arg index="0" value="Queue.receive.default" />
 </bean>

 

然后在代码中有如下代码:
         JmsTemplate jmsTemplate = new JmsTemplate();
        jmsTemplate.setConnectionFactory(defaultConnectionFactory);
        jmsTemplate.setDefaultDestination(defaultDestination);
        jmsTemplate.setMessageConverter(defaultMessageConverter);
        jmsTemplate.setReceiveTimeout(timeOut);
        jmsTemplate.setSessionTransacted(true);// 设置为带事务控制,以便参与到jta事务中

       Object rO = jmsTemplate.receiveSelectedAndConvert(messageSelector);

 

按道理,应该可以参与到JTA事务中来。但是事实没有,然后跟踪dug跟踪spring代码,发现在JmsTemplate在接收消息的时候,会创建Session,这个时候调用以下这个方法:

protected Session createSession(Connection con) throws JMSException {
  return con.createSession(isSessionTransacted(), getSessionAcknowledgeMode());
 }

红色的方法返回的是true,按照JMS规范,创建的session应该是带事务的。

 

然后在接收消息的方法中有以下代码:

if (session.getTransacted()) {
    // Commit necessary - but avoid commit call within a JTA transaction.
    if (isSessionLocallyTransacted(session)) {
     // Transacted session created by this template -> commit.
     JmsUtils.commitIfNecessary(session);
    }
   }
   else if (isClientAcknowledge(session)) {
    // Manually acknowledge message, if any.
    if (message != null) {
     message.acknowledge();
    }
   }
   return message;

红色代码返回的却是false,因此导致没有参与到jta事务中来

 

不知道这个问题是不是activemq的bug,请大家帮忙!!谢谢了!

 

   发表时间:2012-01-31  
con.createSession(isSessionTransacted(), getSessionAcknowledgeMode());
这一句在用XA的时候,参数都是没有意义的。
XA必须用在一个事务管理器、事务上下文中。
0 请登录后投票
   发表时间:2012-02-01  
kimmking 写道
con.createSession(isSessionTransacted(), getSessionAcknowledgeMode());
这一句在用XA的时候,参数都是没有意义的。
XA必须用在一个事务管理器、事务上下文中。


事务管理器我也配置了,配置如下:(我的容器是weblogic10)
<bean id="transactionManager"
class="org.springframework.transaction.jta.WebLogicJtaTransactionManager">
<property name="transactionManagerName"
value="javax.transaction.TransactionManager" />
</bean>

程序中,我是先接受消息,然后记录接收日志入库,这2个操作包含在一个方法里,这个方法外面包了事务的。当出现异常时,数据库操作回滚了(库里没有记录接收日志),但是消息却真正被消费了,没有回滚。


0 请登录后投票
   发表时间:2012-02-02  
容器jndi的UserTransation怎么配置的。

------------------
这个简单的场景不用xa都可以。

session确认模式设置为 CLIENT_ACKNOWLEDGE,
jdbc事务commit以后,consumer再acknowledge
0 请登录后投票
论坛首页 Java企业应用版

跳转论坛:
Global site tag (gtag.js) - Google Analytics