[
https://jira.jboss.org/browse/JBRULES-2717?page=com.atlassian.jira.plugin...
]
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