ActiveMQ JMS XA Atomikos - 事务未启动错误

Posted

技术标签:

【中文标题】ActiveMQ JMS XA Atomikos - 事务未启动错误【英文标题】:ActiveMQ JMS XA Atomikos - Transaction not started error 【发布时间】:2011-09-07 15:16:48 【问题描述】:

情况是我们想使用 XA 事务来协调 ActiveMQ 和 Hibernate (Sql Server 2008) 之间的活动。

我们正在使用:

春季 3.0.5 休眠 3.6.2 ActiveMQ 5.5.0 Atomikos 3.7

我们看到在与事务相关的日志文件中生成了以下错误尚未启动。这些总是与 JMS 相关。

事务“[ID]”尚未开始。

这些一直生成到日志中。

问题更复杂,因为我们有 3 个使用相同 JMS 队列的 Web 应用程序,并且当仅运行一个 Web 应用程序时似乎不会生成错误。

这些被部署到在同一台机器上运行的 Tomcat 7.0.14 的不同实例。

2011-05-31 15:04:27,065 [Atomikos:30] WARN  - [com.atomikos.diagnostics.Slf4jConsole] : XA resource 'XAJMS': rollback for XID '3139322E3136382E302E35332E746D30363636333030303031:3139322E3136382E302E35332E746D36363633' raised 0: unknown
javax.transaction.xa.XAException: Transaction 'XID:1096044365:3139322e3136382e302e35332e746d30363636333030303031:3139322e3136382e302e35332e746d36363633' has not been started.
    at org.apache.activemq.TransactionContext.toXAException(TransactionContext.java:732)
    at org.apache.activemq.TransactionContext.rollback(TransactionContext.java:497)
    at com.atomikos.datasource.xa.XAResourceTransaction.rollback(XAResourceTransaction.java:690)
    at com.atomikos.icatch.imp.RollbackMessage.send(RollbackMessage.java:72)
    at com.atomikos.icatch.imp.PropagationMessage.submit(PropagationMessage.java:111)
    at com.atomikos.icatch.imp.Propagator$PropagatorThread.run(Propagator.java:87)
    at com.atomikos.icatch.imp.Propagator.submitPropagationMessage(Propagator.java:66)
    at com.atomikos.icatch.imp.HeurHazardStateHandler.onTimeout(HeurHazardStateHandler.java:124)
    at com.atomikos.icatch.imp.CoordinatorImp.alarm(CoordinatorImp.java:1105)
    at com.atomikos.timing.PooledAlarmTimer.notifyListeners(PooledAlarmTimer.java:112)
    at com.atomikos.timing.PooledAlarmTimer.run(PooledAlarmTimer.java:99)
    at java.util.concurrent.ThreadPoolExecutor$Worker.runTask(ThreadPoolExecutor.java:886)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:908)
    at java.lang.Thread.run(Thread.java:662)
Caused by: javax.transaction.xa.XAException: Transaction 'XID:1096044365:3139322e3136382e302e35332e746d30363636333030303031:3139322e3136382e302e35332e746d36363633' has not been started.
    at org.apache.activemq.broker.TransactionBroker.getTransaction(TransactionBroker.java:290)
    at org.apache.activemq.broker.TransactionBroker.rollbackTransaction(TransactionBroker.java:177)
    at org.apache.activemq.broker.MutableBrokerFilter.rollbackTransaction(MutableBrokerFilter.java:131)
    at org.apache.activemq.broker.TransportConnection.processRollbackTransaction(TransportConnection.java:436)
    at org.apache.activemq.command.TransactionInfo.visit(TransactionInfo.java:104)
    at org.apache.activemq.broker.TransportConnection.service(TransportConnection.java:306)
    at org.apache.activemq.broker.TransportConnection$1.onCommand(TransportConnection.java:179)
    at org.apache.activemq.transport.TransportFilter.onCommand(TransportFilter.java:69)
    at org.apache.activemq.transport.WireFormatNegotiator.onCommand(WireFormatNegotiator.java:113)
    at org.apache.activemq.transport.InactivityMonitor.onCommand(InactivityMonitor.java:227)
    at org.apache.activemq.transport.TransportSupport.doConsume(TransportSupport.java:83)
    at org.apache.activemq.transport.tcp.TcpTransport.doRun(TcpTransport.java:220)
    at org.apache.activemq.transport.tcp.TcpTransport.run(TcpTransport.java:202)
    at java.lang.Thread.run(Unknown Source)

我们的 Spring 配置:

<Resource name="jms/ConnectionFactory" 
    auth="Container" 
    type="org.apache.activemq.ActiveMQXAConnectionFactory" 
    description="JMS XA Connection Factory"
    factory="org.apache.activemq.jndi.JNDIReferenceFactory" 
    brokerURL="tcp://$activemq.server.name:$activemq.server.port" 
    brokerName="LocalActiveMQBroker" />


<bean id="atomikosConnectionFactory"  
      class="com.atomikos.jms.AtomikosConnectionFactoryBean"  
      init-method="init" destroy-method="close"> 
    <property name="uniqueResourceName" value="XAJMS" /> 
    <property name="xaConnectionFactory" ref="jmsConnectionFactory" />
    <property name="maxPoolSize" value="40" />
</bean>

<bean id="getSomeStuffListenerAdapter" 
      class="org.springframework.jms.listener.adapter.MessageListenerAdapter">
    <property name="delegate" ref="targetElement" />
    <property name="defaultListenerMethod" value="doStuff" />
    <property name="messageConverter" ref="myMessageConverter" />
</bean>

<bean id="getSomeStuffListenerContainer" 
      class="org.springframework.jms.listener.DefaultMessageListenerContainer"
      depends-on="txManager">
    <property name="connectionFactory" ref="atomikosConnectionFactory"/>
    <property name="destination" ref="jmsQueue01"/>
    <property name="messageListener" ref="getSomeStuffListenerAdapter" />
    <property name="concurrency" value="5-10" />
    <property name="transactionManager" ref="txManager" />
    <property name="sessionTransacted" value="true" /> 
</bean>

<bean id="atomikosTransactionManager"
      class="com.atomikos.icatch.jta.UserTransactionManager"
      depends-on="dataSource, atomikosConnectionFactory"
      init-method="init" destroy-method="close">
    <property name="forceShutdown" value="false" /> 
</bean>

<bean id="txManager"
      class="org.springframework.transaction.jta.JtaTransactionManager"> 
    <property name="transactionManager" ref="atomikosTransactionManager" />
</bean>

【问题讨论】:

【参考方案1】:

好的,我们在同一台机器上运行 3 个 Tomcat Web 应用程序时遇到了这个问题,使用 Atomikos,它们指向同一个 ActiveMQ 服务器。

应用程序在具有单独 Atomikos 日志文件的单独 Tomcat 实例中运行。

问题是 XA XID(事务 ID)在三个应用程序中不是唯一的,这导致 ActiveMQ 感到困惑。这是因为实例在同一台机器上运行。

如果您将 Atomikos 和 ActiveMQ 日志记录设置为 TRACE。然后可以看到两个或多个应用程序生成了同一个XID。

这是因为 Atomikos 属性设置:com.atomikos.icatch.tm_unique_name

如果不设置,则生成XID时使用机器的IP地址,这三个应用程序相同,并导致冲突。

只有在 3 个 Tomcat 应用程序彼此非常靠近时才会出现此问题。

因此,将 com.atomikos.icatch.tm_unique_name 设置为每个 Web 应用程序的唯一名称,问题就消失了。

【讨论】:

以上是关于ActiveMQ JMS XA Atomikos - 事务未启动错误的主要内容,如果未能解决你的问题,请参考以下文章

解决mysql 允许执行 XA RECOVER语句(atomikos 解决分布式事务报错)

ActiveMQ基本知识

常用消息中间件的比较-rocketmq,kafka,activemq,rabbitmq

用于 JMS 和 DB 操作的 XA 或非 XA

ActiveMQ 与 JMS

使用 JMS (ActiveMQ) 进行单元测试