使用Spring,可以通过DefaultMessageListenerContainer在外部事务上下文中接收消息。
然而,编写消息的唯一有文档记录的方式是通过JmsTemplate.send(…),我不知道如何强迫它使用给定的TransactionManager。
谁能给我指明正确的方向?
更多信息:确保事务管理器可用(WebSphereUowTransactionManager),使用JmsTemplate.write与Oracle AQjmsFactory.getQueueConnectionFactory(dataSource)进行比较,结果如下:
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不尝试提交。将随着我了解更多信息而更新。
发布于 2011-05-12 07:31:06
我的理解是JMS生产者本质上是通过JTA进行事务处理的。通过JTA发送消息,将使用线程本地的MessageProducer事务(如果存在的话)。
这是由Spring手册(第21.2.5款)暗示的:
JmsTemplate还可以与JtaTransactionManager和一个支持XA的JMSConnectionFactory一起使用,以执行分布式事务。请注意,这需要使用JTA事务管理器以及正确配置的ConnectionFactory。
这也是由JmsAccessor.setSessionTransacted (JmsTemplate的超类) (javadoc )提出的。
设置在创建JMS会话时使用的事务模式。默认值为"false“。
create(Queue/Topic)Session(boolean transacted, int acknowledgeMode)注意,在JTA事务中,传递给方法的参数不被考虑。根据J2EE事务上下文,容器对这些值做出自己的决定。类比地说,在本地管理的事务中也不考虑这些参数,因为在本例中,访问器对现有的JMS会话进行操作。 在托管事务外部运行时,将此标志设置为"true“将使用一个短的本地JMS事务,如果存在托管事务( XA事务除外),则使用同步的本地JMS事务。后者的效果是与主事务(可能是原生JDBC事务)一起管理本地JMS事务,JMS事务在主事务之后提交。
因此,通过启动一个JTA (即使用JtaTransactionManager的transaction )并调用JmsTemplate.send(...),您将发送绑定到该事务的消息。
https://stackoverflow.com/questions/5974601
复制相似问题