Standalone spring app XA transactions with IBM MQ and Oracle as resources

百般思念 提交于 2021-02-19 07:11:27

问题


I am in the process of developing a stand alone Apache camel application (not running on a J2EE container). This apps needs to be capable of routing messages from an IBM MQ queue manager to an Oracle database in a distributed transaction. My google searches pretty much took me to a few places but none of those were able to give me some good clues about how to put everything together. This link below was the closest to what I need but unfortunately it is not cler enough to put me on the right path.

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

Thank you in advance for your inputs.


回答1:


You will need to use a JTA TransactionManager, but since not being in a j2ee container i would sugest to use Atomikos.

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

My route which is working with IBM MQ -> Oracle Database, in an J2EE yes but still should be working with Atomikos setup. I would say this isn't the proper way to to it, but it's the only way I managed to get it working - working well enough for my use case.

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()
;

The commit are handled by the transaction manager, so if I actually get an error with the database commit, it should rollback the message. Next problem that I have had with rollbacking messages is that I can't set the deadLetterQueue, as you can with ActiveMQ. So it rolls back to the incoming queue. Therefore I actually handle the database transaction as I do, it is in a new transaction, which is rollbacked in case of a normal SQLException when calling the database.

I wished this worked:

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

I have posted about this in the community forums but no answers at all.



来源:https://stackoverflow.com/questions/31374595/standalone-spring-app-xa-transactions-with-ibm-mq-and-oracle-as-resources

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!