[jboss-jira] [JBoss JIRA] (DROOLS-282) Create a "CommandSessionCommandService" implementation that does not use an application-scoped persistence context
Marco Rietveld (JIRA)
jira-events at lists.jboss.org
Thu Oct 3 11:06:02 EDT 2013
[ https://issues.jboss.org/browse/DROOLS-282?page=com.atlassian.jira.plugin.system.issuetabpanels:all-tabpanel ]
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: http://www.atlassian.com/software/jira
More information about the jboss-jira
mailing list