Mitch A
Mitch A

Reputation: 2098

Does Spring.NET [Transaction] attribute support multiple transaction managers?

I've been using Spring.NET declarative Transaction management for some time in a code base that uses IBatis in conjunction with the TxScopeTransactionManager. I just added Spring.NET NHibernate support to the project (using OSIV pattern) without issue. NHibernate will be used for new features only, ADO.NET/IBatis legacy data access code still needs to work as is. So I now have two distinct transaction managers in my context:

  1. Spring.Data.Core.TxScopeTransactionManager (existing Tran Mgr)
  2. Spring.Data.NHibernate.HibernateTransactionManager (added for Nhibernate)

However, it looks like Spring.NET only allows a single TransactionManager to be bound to the Transaction attribute because legacy service methods decorated with this attribute are now using HibernateTransactionManager instead of TxScopeTransactionManager to commit or rollback transactions. This is problematic since HibernateTransactionManager is not aware of any non-nHibernate (read ADO.NET) connections.

Is there a way to have [Transaction] use different Transaction Managers, perhaps in concert with the ObjectNameAutoProxyCreator to either include/exclude service classes based on namespace?

If not, is there a way to have a single transactionManager handle both NHibernate and IBatis transactions?

I tested this using HibernateTransactionManager to manage both Data Access strategies, but my IBatis transactions aren't getting rolled back. This is particularly odd, because I can see in SQL Profiler that both a Begin Tran and Rollback Tran are being sent by HibernateTransactionManager, but the data still gets committed.

If I use TxScopeTransactionManager, then my IBatis transactions rollback successfully but NHibernate writes to the DB are never flushed.

Upvotes: 1

Views: 1679

Answers (1)

tobsen
tobsen

Reputation: 5398

According to the Java documentation the @Transaction Attribute in the Java implementation of Spring has an additional parameter which is used to reference the transaction manager to use. This doesn't exist in spring.net today (I haven't found it in version 1.3.2) but I found a DelegatingTransactionAttributeWithName which at first sight seems to be related but I don't know how to use it.

Nevertheless, even if it doesn't you have the following possibilities to use multiple TransactionManagers:

  • Implement your own "DelegatingTransactionManager" by deriving from AbstractPlatformTransactionManager and extend the [Transaction] Attribute to mimic the behaviour the Java world alread has.
  • Use declarative transaction annotation instead of code-based attributes and define separate transactionManagers.

If you are going to go the later route you need to:

  • remove <tx:attribute-driven transaction-manager="transactionManager"/>
  • instead declare two transaction managers (one for Nhibernate, one for Ibatis)
  • declare pointcuts individually for the methods which should use the NhibernateTransactionManager and those methods which should use the Ibatis TransactionManager. The way to declare a transaction manager and pointcuts is described in the second part of the documentation section 17.5.3. Declarative transactions using the transaction namespace just before 17.5.4. Transaction attribute settings.

Even though I haven't tried it myself, this should work. Again the Java guys were first and evolved from there...

Upvotes: 3

Related Questions