【问题标题】:Standalone spring app XA transactions with IBM MQ and Oracle as resources以 IBM MQ 和 Oracle 作为资源的独立 Spring 应用 XA 事务
【发布时间】:2015-10-01 04:47:22
【问题描述】:

我正在开发一个独立的 Apache camel 应用程序(不在 J2EE 容器上运行)。 此应用程序需要能够在分布式事务中将消息从 IBM MQ 队列管理器路由到 Oracle 数据库。 我的谷歌搜索几乎把我带到了几个地方,但没有一个能给我一些关于如何把所有东西放在一起的好线索。 下面的这个链接是最接近我需要的,但不幸的是它不够聪明,无法让我走上正确的道路。

IBM MQManager as XA Transaction Manager with Spring-jms and Spring-tx

提前感谢您的意见。

【问题讨论】:

  • 这个RFE也值得投票;这是关于添加对其他 JTA 事务协调器(不仅仅是 Atomikos)的支持ibm.com/developerworks/rfe/… 我要强调的是,今天的官方支持声明说只能使用 JavaEE 认证的服务器;这是因为在使用 IBM MQ JMS 时,Atomikos 等其他组件尚未经过验证。
  • @Calanais 您提供的链接无效。
  • 您是否进入 IBM ID 登录页面?需要一个 id - 这是免费的,而且创建起来非常简单。
  • 投票已发送,但作为个人意见,我怀疑像 IBM 这样的怪物是否会继续实施并实施这一点,因为这个世界上有四个人要求这样做。不实施也可能是政治
  • 不幸的是 5 年前发布的 rfe @Calanais 并没有前进一点.... 根据 ibm 在 2013 年的评论 Our intention is to provide formal support for any JTA-compliant implementation rather than specific named products. The timescale for this is undetermined.,但不确定这 意图有多好 i> 是今天,因为我无法从 ibm 官方文档中找到任何关于如何将 v7 或更高版本的 jms 客户端与符合 JTA 的 TM 实现相结合的说明/最佳实践.....

标签: spring oracle apache-camel ibm-mq


【解决方案1】:

您将需要使用 JTA TransactionManager,但由于不在 j2ee 容器中,我建议使用 Atomikos。

https://github.com/camelinaction/camelinaction/tree/master/chapter9/xa

我的路线与 IBM MQ -> Oracle 数据库一起使用,在 J2EE 中是的,但仍应与 Atomikos 设置一起使用。我会说这不是正确的方法,但这是我设法让它工作的唯一方法 - 对于我的用例来说工作得很好。

from(inQueue)
    .transacted()
    .setHeader("storeData", constant(false))
    .to("direct:a")
    .choice().when(header("storeData").isEqualTo(false)) // if this is true the database calls are 'successful'
    .log("Sending message to errorQueue")
    .to(errorQueue)
;

StoreDataBean storeDataBean = new StoreDataBean();
from("direct:a")
    .onException(Exception.class).handled(false).log("Rollbacking database changes").markRollbackOnlyLast().end()
    .transacted("PROPAGATION_REQUIRES_NEW")
    .bean(storeDataBean) //storeData sets the header storeData to true if no SQLException or other exceptions are thrown
    .end()
;

提交由事务管理器处理,因此如果我在数据库提交中确实遇到错误,它应该回滚消息。 我在回滚消息时遇到的下一个问题是我无法设置 deadLetterQueue,就像使用 ActiveMQ 一样。所以它回滚到传入队列。所以我实际上是像我一样处理数据库事务,它是在一个新事务中,在调用数据库时如果出现正常的SQLException,它会被回滚。

我希望这能奏效:

from(inQueue)
    .onException(Exception.class).to(errorQueue).markRollbackOnly().end()
    .bean(storeDataBean)
    .end()

我已经在社区论坛上发布了有关此问题的信息,但根本没有答案。

【讨论】:

  • 感谢 J2B 的评论。您指向我的示例正是我所遵循的,并且我确实设法将 Atomikos 放在一起,并且可以在日志条目中看到像 ##14-07-2015 08:43:42,112 [INFO ] atomikos - setRollbackOnly() called for transaction 10.16.164.34.tm0000600003 ##14-07-2015 08:43:42,112 [WARN ] org.apache.camel.spring.spi.TransactionErrorHandler - Transaction rollback (0x560513ce) redelivered(unknown) 这样的条目。但是,我的消息没有回滚到我放入的队列中,而是消失了(如果您认为它是付款消息,那就不好了 :-)
  • 我正在使用没有设置事务管理器方法的 SJMS 组件。我应该切换到 JMS 组件还是我的路由配置中仍然缺少它。与“行动中的骆驼”示例相比,这是我尚未完成的部分<bean id="activemq" class="org.apache.activemq.camel.component.ActiveMQComponent" depends-on="my-broker"> <property name="transacted" value="true"/> <!-- refer to the transaction manager --> <property name="transactionManager" ref="jtaTransactionManager"/> </bean>
  • 好的,所以我让它与 JmsComponent 一起工作。我通过在两个 MQ Webshere 队列管理器和接收者之间移动消息进行了测试,因为目标队列设置为“禁止放置”,因此接收者无法接受该消息。事务回滚到源队列。我仍然需要看到它也可以与数据库一起使用,但是很有信心它会起作用。不过我还是想澄清一下 SJMS 组件是如何设置为事务管理器的。
  • 由于您不是在 J2EE 中工作,我想说测试它更容易!无论如何,我自己在让它按我想要的方式工作方面遇到了问题。请参阅我编辑的答案,因为发布 cmets 时没有足够的字符
  • @Julian 如果您找到更好的解决方案,请分享! :)
猜你喜欢
  • 1970-01-01
  • 2017-01-24
  • 2013-03-10
  • 1970-01-01
  • 2015-06-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2016-01-18
相关资源
最近更新 更多