JBoss环境下JMSTemplate事务会话与MQ资源适配器无法正常工作
问题分析与解决方案
问题根源
你配置的JMSTemplate开启了sessionTransacted=true,意味着要手动管理事务(调用commit/rollback),但JBoss中配置的连接工厂使用XATransaction事务支持,这种情况下会话绑定到容器管理的事务(CMT)中,不允许手动调用commit方法,因此触发JMSCC0014错误。关闭sessionTransacted后,JMSTemplate不再尝试手动提交,转而依赖容器事务或自动确认,功能恢复正常。
解决方案建议
场景1:使用容器管理事务(CMT)
这是Java EE环境下的常规做法,无需手动管理事务:
- 保留现有连接工厂的
XATransaction配置不变 - 修改JMSTemplate配置,将
sessionTransacted设为false:<property name="sessionTransacted" value="false" /> - 在发送/接收消息的业务方法上添加
@Transactional注解,由JBoss容器自动处理事务的提交与回滚
场景2:使用本地手动事务
如果确实需要手动控制事务提交/回滚,需单独配置非XA类型的连接工厂:
- 在JBoss的resource-adapters子系统中,新增一个连接定义,将事务支持改为
LocalTransaction:<connection-definition class-name="com.ibm.mq.connector.outbound.ManagedConnectionFactoryImpl" jndi-name="java:jboss/xxx-local" enabled="true" connectable="true" tracking="false" use-java-context="false" pool-name="xxx-local"> <config-property name="channel">xxx</config-property> <config-property name="hostName">xxx</config-property> <config-property name="transportType">CLIENT</config-property> <config-property name="queueManager">xxx</config-property> <config-property name="port">xxx</config-property> </connection-definition> - 创建专门的JMSTemplate,引用这个非XA连接工厂,并保持
sessionTransacted=true:<bean id="jmstemplateLocal" class="org.springframework.jms.core.JmsTemplate"> <property name="connectionFactory" ref="jmsConnectionFactoryLocal" /> <property name="destinationResolver" ref="jmsDestResolver" /> <property name="sessionAcknowledgeModeName" value="CLIENT_ACKNOWLEDGE" /> <property name="sessionTransacted" value="true" /> </bean>
是否需要两种连接工厂?
- 如果业务中同时存在容器管理事务和手动本地事务的场景,必须配置两种不同事务支持的连接工厂,分别对应不同的JMSTemplate使用
- 如果只需要一种事务模式,只需调整现有配置即可,无需额外配置
内容的提问来源于stack exchange,提问作者Sanjay
相关产品推荐
相关产品推荐

