Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Sharing JMS and Hibernate transactions in a Spring MDB using Oracle Streams AQ?

I'm using Oracle 11g for my database and its Oracle Streams AQ feature as JMS implementation.

For all I know, it should be possible to implement a Spring based message-driven POJO (MDP) that uses the same data source for both transactional data access and JMS transactions -- all without XA-Transactions (IIRC, this was marketed as a feature of SpringSource Advanced Pack for Oracle).

Is this possible using Hibernate as well? Ideally, my MDP would start a JMS transaction and read a message from a queue, then re-use the transaction for data access through Hibernate. If anything goes wrong, the JMS and database transaction would both be rolled back, without using 2-phase commit (2PC).

I'm not much of a transaction guru, so before I start digging deeper, can anyone confirm that this is possible and makes sense as well?

Update:
What I want is an implementation of the Shared Transaction Resource pattern. The sample code demonstrates it for ActiveMQ and JDBC, but I need to use Oracle Streams AQ and Hibernate.

Update2: The SpringSource Advanced Pack for Oracle has been open sourced as part of Spring Data JDBC and it "provides the option of using a single local transaction manager for both database and message access without resorting to expensive distributed 2-phase commit transaction management".

like image 809
otto.poellath Avatar asked Aug 03 '09 18:08

otto.poellath


1 Answers

2PC shouldn't be necessary, as you say, since the appserver should take care of it. However, you'll pretty much have to use JTA (i.e. JavaEE container) transactions, rather than vanilla DataSource transactions, since JMS only works with JTA.

This isn't a big deal, it's just a bit more fiddly:

  1. Your Spring config should use <jee:jndi-lookup/> to get a reference to your container's DataSource, and you inject that data source into your spring-managed hibernate SessionFactory.
  2. You then need to introduce a transaction manager into the context (<tx:jta-transaction-manager/> should work in most app-servers).
  3. In your Spring JMS MessageListenerContainer, plug the above transaction manager reference into it.

Does that all make sense, or should I elaborate? This setup should ensure that the container-managed transactions are held across JMS and Hibernate interactions.

like image 105
skaffman Avatar answered Oct 23 '22 18:10

skaffman