首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >使用Spring JmsTemplate使用TransactionManager编写消息

使用Spring JmsTemplate使用TransactionManager编写消息
EN

Stack Overflow用户
提问于 2011-05-12 07:17:42
回答 1查看 14.5K关注 0票数 1

使用Spring,可以通过DefaultMessageListenerContainer在外部事务上下文中接收消息。

然而,编写消息的唯一有文档记录的方式是通过JmsTemplate.send(…),我不知道如何强迫它使用给定的TransactionManager

谁能给我指明正确的方向?

更多信息:确保事务管理器可用(WebSphereUowTransactionManager),使用JmsTemplate.write与Oracle AQjmsFactory.getQueueConnectionFactory(dataSource)进行比较,结果如下:

代码语言:javascript
复制
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不尝试提交。将随着我了解更多信息而更新。

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2011-05-12 07:31:06

我的理解是JMS生产者本质上是通过JTA进行事务处理的。通过JTA发送消息,将使用线程本地的MessageProducer事务(如果存在的话)。

这是由Spring手册(第21.2.5款)暗示的:

JmsTemplate还可以与JtaTransactionManager和一个支持XA的JMS ConnectionFactory一起使用,以执行分布式事务。请注意,这需要使用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(...),您将发送绑定到该事务的消息。

票数 7
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/5974601

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档