Announcement Announcement Module
Collapse

Spring Dynamic Modules forum decommissioned in favor of Eclipse Gemini Blueprint

With the official first release of Eclipse Gemini Blueprint shipped, the migration of the Spring Dynamic Modules code base to the Eclipse Foundation, as part of the Gemini project, has been completed.

As such, this forum has been decommissioned in favour of the Eclipse Gemini forums.
See more
See less
Transactions propagation through services Page Title Module
Move Remove Collapse
X
Conversation Detail Module
Collapse
  • Filter
  • Time
  • Show
Clear All
new posts

  • Transactions propagation through services

    Hi,

    I'm using Spring-dm on OSGi with Hibernate and I have troubles with transaction management which seems to be not propagated through services. I'd like to know if some of you had the same issue and if there were a fix or a mistake from my side. Let explain.
    My application is composed of multiple bundles. One bundle cares about hibernate ORM. This bundle exposes DAO classes as services, using spring-dm. Some other bundles have references to these DAO interfaces so they get references to the hibernate implementation when the extender runs. DAO are defined using interface so one day i can migrate from hibernate to something else (JPA or whatever) simply by providing a new implementation bundle.
    This works fine as long as DAO are called for simple read/save operations. Now things get worse when I try to access lazily initalized collections for example. Then I get some exception telling me that the collection was initialzed lazily in another session so it can't be retrieved. This seems to be a very common problem when using Hibernate and it can be related to session management and transaction propragation.
    Therefore i've added some trace and ran in debug mode to check what happens on my code when a business method (annotated with @Transaction) runs and call a DAO to get some object and then tries to access a collection inside this objet. DAO methods also use @Transaction so I guess transaction should be propagated from the business method to the DAO method. In fact it happens that inside the DAO a new transaction (and hibernate session) is opened and closed at the end. Therefore back to the business method an exception is thrown.
    Here is the trace:
    Code:
    2008-08-04 11:13:43,380 [Thread-0] DEBUG org.escapek.server.cim.impl.internal.CIMService:296 - --- Entering DAO ---
    2008-08-04 11:13:43,380 [Thread-0] DEBUG o.s.o.c.support.OsgiBundleXmlApplicationContext:273 - Publishing event in context [org.sprin[email protected]2437a4]: org.springframework.osgi.service.importer.event.OsgiServiceDependencyWaitStartingEvent[source=org.springfram[email protected]42aec9]
    2008-08-04 11:13:43,382 [Thread-0] DEBUG o.s.o.c.support.OsgiBundleXmlApplicationContext:273 - Publishing event in context [org.sprin[email protected]2437a4]: org.springframework.osgi.service.importer.event.OsgiServiceDependencyWaitEndedEvent[source=org.springfram[email protected]42aec9]
    2008-08-04 11:13:43,382 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:346 - Using transaction object [org.springframework.orm.hi[email protected]c6b3f7]
    2008-08-04 11:13:43,383 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:374 - Creating new transaction with name [org.escapek.domain.orm.dao.cim.ICIMObjectDao.getByNameAndNS]: PROPAGATION_REQUIRED,ISOLATION_DEFAULT
    2008-08-04 11:13:43,383 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:496 - Opened new Session [[email protected]] for Hibernate transaction
    2008-08-04 11:13:43,383 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:507 - Preparing JDBC Connection of Hibernate Session [[email protected]]
    2008-08-04 11:13:43,384 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:572 - Exposing Hibernate transaction as JDBC transaction [jdbc:oracle:thin:@TN67.admin:1521:TESTDBA, UserName=NICO, Oracle JDBC driver]
    2008-08-04 11:13:43,384 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:186 - Bound value [[email protected]] for key [[email protected]] to thread [Thread-0]
    2008-08-04 11:13:43,384 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:186 - Bound value [[email protected]] for key [[email protected]] to thread [Thread-0]
    2008-08-04 11:13:43,384 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:261 - Initializing transaction synchronization
    2008-08-04 11:13:43,385 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [[email protected]] for key [[email protected]] bound to thread [Thread-0]
    2008-08-04 11:13:43,385 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [[email protected]] for key [[email protected]] bound to thread [Thread-0]
    2008-08-04 11:13:43,386 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [[email protected]] for key [[email protected]] bound to thread [Thread-0]
    2008-08-04 11:13:43,386 [Thread-0] DEBUG o.springframework.orm.hibernate3.HibernateTemplate:410 - Found thread-bound Session for HibernateTemplate
    2008-08-04 11:13:43,386 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [[email protected]] for key [[email protected]] bound to thread [Thread-0]
    2008-08-04 11:13:43,411 [Thread-0] DEBUG o.springframework.orm.hibernate3.HibernateTemplate:435 - Not closing pre-bound Hibernate Session after HibernateTemplate
    2008-08-04 11:13:43,412 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:880 - Triggering beforeCommit synchronization
    2008-08-04 11:13:43,412 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:893 - Triggering beforeCompletion synchronization
    2008-08-04 11:13:43,413 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:707 - Initiating transaction commit
    2008-08-04 11:13:43,413 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:651 - Committing Hibernate transaction on Session [[email protected]]
    2008-08-04 11:13:43,415 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:906 - Triggering afterCommit synchronization
    2008-08-04 11:13:43,415 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:922 - Triggering afterCompletion synchronization
    2008-08-04 11:13:43,416 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:315 - Clearing transaction synchronization
    2008-08-04 11:13:43,417 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:232 - Removed value [org.springframework.orm[email protected]] for key [[email protected]] from thread [Thread-0]
    2008-08-04 11:13:43,417 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:232 - Removed value [[email protected]] for key [[email protected]] from thread [Thread-0]
    2008-08-04 11:13:43,418 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:730 - Closing Hibernate Session [[email protected]] after transaction
    2008-08-04 11:13:43,418 [Thread-0] DEBUG o.s.orm.hibernate3.SessionFactoryUtils:774 - Closing Hibernate Session
    2008-08-04 11:13:43,419 [Thread-0] DEBUG org.escapek.server.cim.impl.internal.CIMService:298 - --- Exiting DAO ---
    as shown the Hibernate session is closed when the DAO ends. I assume the transaction opened by the business method should be propagated to the DAO and kept opened when going back from the DAO. That's why I guess there should be a problem here due to the fact that the DAO is an exposed OSGi service.

    Note that when removing lazy initialization, everything works fine.

    Any idea or comment ? I hope I made myself clear ...

  • #2
    As I say on this duplicate thread , I guess the problem comes from the AOP interceptor which can only intercept @Transactional method calls made from the bundle where the application context has been defined. As my CIMService is in a different bundle, I guess it can't be intercepted and therefore can't be added to an existing transaction in the transaction manager. Transactions and AOP experts could be able to give the correct explanations.
    Nevertheless, to try to fix this problem, I've tried the following:
    • Export the HibernateTransactionManager as an osgi service:
      Code:
          <osgi:service ref="txManager"
          	interface="org.springframework.transaction.PlatformTransactionManager" />
    • Import this service reference in the bundle where CIMService is:
      Code:
      <reference id="txManager" interface="org.springframework.transaction.PlatformTransactionManager" />
    • Add the transaction interceptor to CIMService application context:
      Code:
      	<tx:annotation-driven transaction-manager="txManager"/>

    Using this trick, the run trace is now:

    Code:
    2008-08-05 14:33:39,421 [Thread-0] DEBUG org.escapek.server.cim.impl.internal.CIMService:604 - -> CIMService.findParentClassProperty 
    2008-08-05 14:33:39,422 [Thread-0] DEBUG o.s.t.a.AnnotationTransactionAttributeSource:107 - Adding transactional method [read] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly]
    2008-08-05 14:33:39,422 [Thread-0] DEBUG o.s.o.c.support.OsgiBundleXmlApplicationContext:273 - Publishing event in context [org.sprin[email protected]b84bea]: org.springframework.osgi.service.importer.event.OsgiServiceDependencyWaitStartingEvent[source=org.springfram[email protected]824760]
    2008-08-05 14:33:39,422 [Thread-0] DEBUG o.s.o.c.support.OsgiBundleXmlApplicationContext:273 - Publishing event in context [org.sprin[email protected]b84bea]: org.springframework.osgi.service.importer.event.OsgiServiceDependencyWaitEndedEvent[source=org.springfram[email protected]824760]
    2008-08-05 14:33:39,423 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [[email protected]] for key [[email protected]] bound to thread [Thread-0]
    2008-08-05 14:33:39,423 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:442 - Found thread-bound Session [[email protected]] for Hibernate transaction
    2008-08-05 14:33:39,423 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [[email protected]] for key [[email protected]] bound to thread [Thread-0]
    2008-08-05 14:33:39,424 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:346 - Using transaction object [org.springframework.orm.hi[email protected]11cd6a]
    2008-08-05 14:33:39,424 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:471 - Participating in existing transaction
    2008-08-05 14:33:39,425 [Thread-0] DEBUG o.s.o.c.support.OsgiBundleXmlApplicationContext:273 - Publishing event in context [org.sprin[email protected]b84bea]: org.springframework.osgi.service.importer.event.OsgiServiceDependencyWaitStartingEvent[source=org.springfram[email protected]671233]
    2008-08-05 14:33:39,425 [Thread-0] DEBUG o.s.o.c.support.OsgiBundleXmlApplicationContext:273 - Publishing event in context [org.sprin[email protected]b84bea]: org.springframework.osgi.service.importer.event.OsgiServiceDependencyWaitEndedEvent[source=org.springfram[email protected]671233]
    2008-08-05 14:33:39,426 [Thread-0] DEBUG o.s.t.a.AnnotationTransactionAttributeSource:107 - Adding transactional method [read] with attribute [PROPAGATION_REQUIRED,ISOLATION_DEFAULT,readOnly]
    2008-08-05 14:33:39,426 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [[email protected]] for key [[email protected]] bound to thread [Thread-0]
    2008-08-05 14:33:39,427 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:442 - Found thread-bound Session [[email protected]] for Hibernate transaction
    2008-08-05 14:33:39,427 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [[email protected]] for key [[email protected]] bound to thread [Thread-0]
    2008-08-05 14:33:39,428 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:346 - Using transaction object [org.springframework.orm.hi[email protected]c1c434]
    2008-08-05 14:33:39,428 [Thread-0] DEBUG o.s.orm.hibernate3.HibernateTransactionManager:471 - Participating in existing transaction
    2008-08-05 14:33:39,428 [Thread-0] DEBUG o.e.domain.orm.hibernate.internal.dao.CIMClassDao:50 - -> CIMClassDao.read
    2008-08-05 14:33:39,429 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [[email protected]] for key [[email protected]] bound to thread [Thread-0]
    2008-08-05 14:33:39,430 [Thread-0] DEBUG o.s.t.support.TransactionSynchronizationManager:142 - Retrieved value [[email protected]] for key [[email protected]] bound to thread [Thread-0]
    2008-08-05 14:33:39,430 [Thread-0] DEBUG o.springframework.orm.hibernate3.HibernateTemplate:410 - Found thread-bound Session for HibernateTemplate
    2008-08-05 14:33:39,430 [Thread-0] DEBUG o.springframework.orm.hibernate3.HibernateTemplate:435 - Not closing pre-bound Hibernate Session after HibernateTemplate
    2008-08-05 14:33:39,431 [Thread-0] DEBUG o.e.domain.orm.hibernate.internal.dao.CIMClassDao:54 - <- CIMClassDao.read
    2008-08-05 14:33:39,431 [Thread-0] DEBUG o.s.o.c.support.OsgiBundleXmlApplicationContext:273 - Publishing event in context [org.sprin[email protected]b84bea]: org.springframework.osgi.service.importer.event.OsgiServiceDependencyWaitStartingEvent[source=org.springfram[email protected]824760]
    2008-08-05 14:33:39,432 [Thread-0] DEBUG o.s.o.c.support.OsgiBundleXmlApplicationContext:273 - Publishing event in context [org.sprin[email protected]b84bea]: org.springframework.osgi.service.importer.event.OsgiServiceDependencyWaitEndedEvent[source=org.springfram[email protected]824760]
    2008-08-05 14:33:39,432 [Thread-0] DEBUG org.escapek.server.cim.impl.internal.CIMService:607 - ---
    2008-08-05 14:33:39,500 [Thread-0] DEBUG org.escapek.server.cim.impl.internal.CIMService:612 - <- CIMService.findParentClassProperty
    As shown, the existing transaction is now retrieved as the hibernate session. LazyInitException is not thrown anymore when accessing the collection !

    Comment

    Working...
    X