-
Enhancement
-
Resolution: Unresolved
-
Major
-
None
-
6.0.0.Final
-
None
-
None
-
High
The application scoped persistence context (EntityManager) causes a race-condition when a persistence KieSession is accessed by multiple threads in which the transaction is not managed by the KieSession but by code outside of the drools/jbpm/kie code base.
A "CommandSessionCommandService" implementation would work very similarly to the existing SingleSessionCommandService implementation: in both implementations, each thread would use it's own command scoped entity manager.
However, the CommandSessionCommandService would not use an EntityManager that would be used by multiple threads.
The race-condition that arises due to the use of an application scoped entity manager is due to the following:
- The JPA spec clearly states that the EntityManager is not thread-safe.
- As a result of this Hibernate (and probably other ORM frameworks) only has one internal object to represent whether or not the EntityManager(Impl) has joined a transaction or not.
- For JTA, Hibernate uses the JTA Synchronization mechanism (normal, not interposed) in order to reset this status once a transaction has committed.
- When one thread calls tx.commit() while another thread calls em.joinTransaction(), then a race-condition can happen in which the "joined transaction" status is first set by the EntityManager.joinTransaction() call after which the status is reset to not-joined by the Hibernate injected JTA Synchronization instance in it's afterCompletion(..) method).
Occasionally, the call to EntityManager.joinTransaction() will fail because of this race-condtion, although the more dangerous situation is one in which .joinTransaction() does not throw an exception but where the race-condition does happen.
I've made a trivial effort to create this implementation and discovered that it's more difficult than I had initially expected.
- blocks
-
JBPM-3814 Session thread safe support in JTA/EE environment
- Closed