[jboss-jira] [JBoss JIRA] Commented: (JBRULES-2717) DroolsSpringJpaManager Creates Two Different Entity Managers Bound to the Same Thread
Anatoly Polinsky (JIRA)
jira-events at lists.jboss.org
Fri Nov 12 15:06:36 EST 2010
[ https://jira.jboss.org/browse/JBRULES-2717?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=12563185#comment-12563185 ]
Anatoly Polinsky commented on JBRULES-2717:
-------------------------------------------
Drools Team,
Not sure what the true reason is for having both: an "application scoped entity manager" and a "command scope entity manager" within a single Transaction Manager, but it introduces _more_ problems than it solves.
I suspect that the overall reason was to either have a framework own transaction that deals with framework entities OR to some how cache those entities using a persistence cache. So having that my assumption is correct, let's look at the two:
1. Have a framework own transaction that deals with framework entities.
This just makes no sense whatsoever in case a RESOURCE_LOCAL transaction is used. And yes, I am still convinced distributed transactions are not needed in most of the BPM cases.
2. Caching framework entities using a persistence cache.
Clever, but very dangerous, since an "application scoped entity manager" is in reality becomes an EXTENDED persistence context, which is NOT thread safe + in the current "DroolsSpringJpaManager" implementation, it tries to join the innocent transaction from a "command scoped entity manager" thread. Again, in none JTA implementation it just does not make much sense.
Caching should be addressed by various distributed cache implementations with Data Store SPIs, rather then introducing another transactional resource.
If you ever stress test drools flow by spawning multiple threads that would ( using a KnowledgeStoreService ) start / load medium complexity processes [ subflows, foreached, suspends, resumes, multiple activities in progress, etc.. ] you'd see that results are just unpredictable due to the fact that an "application scoped entity manager" either gets closed, because it is confused which transaction it belongs to, or it just has inconsistent cache state ( NonUnique, Detached, NullPointer, and other friendly exception coming from it ).
I trust that Drools team knows what it is doing, but what I would like to ask is, for people like us, 100+ developers size project, that actually uses Drools Flow, rather than playing with toy projects, as most of the people on the mailing list, please think on providing a Convention Over Configuration approach, where we do _not_ have to deal with more than one entity manager throughout the whole application unless _we_ need to.
Thank you,
/Anatoly
> DroolsSpringJpaManager Creates Two Different Entity Managers Bound to the Same Thread
> -------------------------------------------------------------------------------------
>
> Key: JBRULES-2717
> URL: https://jira.jboss.org/browse/JBRULES-2717
> Project: Drools
> Issue Type: Bug
> Security Level: Public(Everyone can see)
> Affects Versions: 5.1.1.FINAL
> Environment: N/A
> Reporter: Anatoly Polinsky
> Assignee: Mark Proctor
> Labels: drools_persistence
> Original Estimate: 4 hours
> Remaining Estimate: 4 hours
>
> org.drools.container.spring.beans.persistence.DroolsSpringJpaManager
> creates two DIFFERENT entity managers for the SAME thread:
> ApplicationScoped ... = this.emf.createEntityManager();
> CommandScoped ... = this.emf.createEntityManager();
> I am sure there should be a good reason for it [ not sure what it is though, since it is not documented ], but... It breaks drools-flow clients if they already came with "their own" entity manager.
> ApplicationScoped code is smart enough to check if there is already an entity manager factory bound to thread:
> EntityManagerHolder emHolder = ( EntityManagerHolder ) TransactionSynchronizationManager.getResource( this.emf );
> if ...
> emHolder.getEntityManager();
> CommandScoped however is completely disrespectful to the thread, and only checks for its own key is in the ts manager:
> EntityManagerHolder emHolder = ( EntityManagerHolder ) TransactionSynchronizationManager.getResource( "cmdEM" );
> So all processes end up with two different entity managers, which actually causes problems for the calling code that manipulates entities that are changed within the drools process ( optimistic locking: makes sense, since the version fields are changed by two entirely different entity managers )
> Again, I am not sure what the whole purpose of this is, but we are using a RESOURCE_LOCAL transaction, and once I have "CommandScoped" change to follow the "TransactionSynchronizationManager.getResource( this.emf )" approach, the calling code works fine.
> /Anatoly
--
This message is automatically generated by JIRA.
-
For more information on JIRA, see: http://www.atlassian.com/software/jira
More information about the jboss-jira
mailing list