Announcement Announcement Module
No announcement yet.
Transaction propagation failure Page Title Module
Move Remove Collapse
Conversation Detail Module
  • Filter
  • Time
  • Show
Clear All
new posts

  • Transaction propagation failure

    Hello all,

    I apologize if this question has already been asked, but I couldn't locate any references to a situation like mine.

    I have 2 modules, each has its own HibernateSessionFactory using the same datasource definition (mysql). ModuleA.methodA() calls ModuleB.methodB(). Both ModuleA.methodA() and ModuleB.methodB() have transactional properties declared as PROPAGATION_REQUIRED. Spring, however, fails with :

    java.lang.IllegalStateException: Already value [org.springframework.jdbc.datasource.ConnectionHold [email protected]] for key [[email protected]] bound to thread [main]

    Looking a little into the spring source code, it appears that new transactions are created or re-used based on their association with the given SessionFactory. In my case I use 2 different SessionFactories with their own sets of DAO definitions, so spring creates a new transaction for the ModuleB.methodB() call. However, after it is done, the TransactionSynchronizationManager is instructed to bind the transaction to the data source and in my case it is the same for both modules. Hence, the exception.

    Is my set-up unsupported or unworkable? Any comments.


  • #2
    I assume you're using two HibernateTransactionManagers, i.e. one for each of your SessionFactory instance, pointing to the same DataSource. In that case, switch HibernateTransactionManager's "autodetectDataSource" property to "false", possibly on both transaction manager instances.

    Neither of your interweaved Hibernate transactions will then get exposed as JDBC transaction. Alternatively, choose one transaction manager to expose JDBC transactions - never both, though, as they will interfere just like you experienced. I guess you're not using direct JDBC access code anyway, though, so I recommend to simply turn off the "autodetectDataSource" flag on both transaction managers.



    • #3
      Thank you, I will definitely try it.

      I do wonder, however, whether the transaction is going to be properly propagated, i.e. committed or rolled back in the inner session factory in sync with the transaction in the outer factory.

      Also, can you comment whether creating a session factory for each 'module' in the system is a viable option, or whether it's better to always have one session for the whole application. The driving motivation for me is that I develop fairly stand-alone library-like modules which can be deployed as part of a larger application by being simply 'dropped-in'.



      • #4
        One way you can do component oriented programming is for each module to refer to their dependencies by a module specific name, i.e.
        then somewhere else (the app itself that uses the modules), you actually define the datasource, and provide aliases which match all the names that other modules are using. All the xml file fragments get combined into one application context...