]
Marco Rietveld updated DROOLS-282:
----------------------------------
Attachment: app-scoped-em-race-condition-example.txt
Added a stack trace that illustrates the race-condition.
Create a "CommandSessionCommandService" implementation that
does not use an application-scoped persistence context
------------------------------------------------------------------------------------------------------------------
Key: DROOLS-282
URL:
https://issues.jboss.org/browse/DROOLS-282
Project: Drools
Issue Type: Enhancement
Security Level: Public(Everyone can see)
Affects Versions: 6.0.0.Final
Reporter: Marco Rietveld
Assignee: Marco Rietveld
Attachments: app-scoped-em-race-condition-example.txt
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.
--
This message is automatically generated by JIRA.
If you think it was sent incorrectly, please contact your JIRA administrators
For more information on JIRA, see: