使用TransactionManager使用Spring JmsTemplate编写消息

| 使用Spring-JMS,可以通过DefaultMessageListenerContainer在外部事务上下文中接收消息。 但是,编写消息的唯一记录方式是通过
JmsTemplate.send(…)
,我看不到如何强制使用给定的ѭ1this。 谁能指出我正确的方向? 更多信息:确保事务管理器可用(
WebSphereUowTransactionManager
),对Oracle
AQjmsFactory.getQueueConnectionFactory(dataSource)
使用
JmsTemplate.write
会导致:
org.springframework.jms.UncategorizedJmsException: Uncategorized exception occured during JMS processing; nested exception is oracle.jms.AQjmsException: could not use local transaction commit in a global transaction
  at org.springframework.jms.support.JmsUtils.convertJmsAccessException(JmsUtils.java:316)
  at org.springframework.jms.support.JmsAccessor.convertJmsAccessException(JmsAccessor.java:168)
  at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:469)
  at org.springframework.jms.core.JmsTemplate.send(JmsTemplate.java:534)
Caused by: oracle.jms.AQjmsException: could not use local transaction commit in a global transaction
  at oracle.jms.AQjmsSession.commitNoCheck(AQjmsSession.java:1053)
  at oracle.jms.AQjmsSession.commit(AQjmsSession.java:1021)
  at org.springframework.jms.support.JmsUtils.commitIfNecessary(JmsUtils.java:217)
  at org.springframework.jms.core.JmsTemplate.doSend(JmsTemplate.java:573)
  at org.springframework.jms.core.JmsTemplate$3.doInJms(JmsTemplate.java:536)
  at org.springframework.jms.core.JmsTemplate.execute(JmsTemplate.java:466)
  ... 24 more
Caused by: java.sql.SQLException: could not use local transaction commit in a global transaction
  at oracle.jdbc.driver.PhysicalConnection.disallowGlobalTxnMode(PhysicalConnection.java:6647)
  at oracle.jdbc.driver.PhysicalConnection.commit(PhysicalConnection.java:3635)
  at oracle.jdbc.driver.PhysicalConnection.commit(PhysicalConnection.java:3680)
  at oracle.jdbc.OracleConnectionWrapper.commit(OracleConnectionWrapper.java:133)
  at oracle.jms.AQjmsSession.commitNoCheck(AQjmsSession.java:1049)
  ... 29 more
因此,尽管我没有理由怀疑下面的建议,但由于无法弄清楚如何使AQ JMS不尝试提交,因此无法对其进行测试。将会随着我的了解而更新。     
已邀请:
我的理解是,JMS生产者本质上是通过JTA进行交易的。通过JMS
MessageProducer
发送消息,就使用了线程本地的JTA事务(如果存在的话)。 Spring手册(第21.2.5节)暗示了这一点:   
JmsTemplate
还可以与
JtaTransactionManager
和具有XA功能的JMS
ConnectionFactory
一起使用,以执行分布式事务。请注意,这需要使用JTA事务管理器以及经过XA配置的正确的“ 9”。
JmsAccessor.setSessionTransacted
JmsTemplate
的超类)(javadoc)也建议这样做:   设置创建JMS会话时使用的事务模式。默认值为\“ false \”。   请注意,在JTA事务中,不考虑传递给
create(Queue/Topic)Session(boolean transacted, int acknowledgeMode)
方法的参数。取决于J2EE事务上下文,容器将对这些值做出自己的决定。类似地,在本地管理的事务中也不考虑这些参数,因为在这种情况下访问器在现有的JMS会话上进行操作。      将此标志设置为“ true”会在托管事务之外运行时使用简短的本地JMS事务,如果存在托管事务(XA事务除外),则将使用同步的本地JMS事务。后者的作用是与主要事务(可能是本地JDBC事务)一起管理本地JMS事务,并且JMS事务在主要事务之后立即提交。 因此,通过启动JTA事务(即通过使用Spring的事务API和
JtaTransactionManager
)并调用and15ѭ,您将发送绑定到该事务的消息。     

要回复问题请先登录注册