]
Anatoly Polinsky updated JBRULES-2793:
--------------------------------------
Attachment: env.get.em.png
files that are effected by accessing command scoped entity manager in a non-thread safe
manner
Storing Entity Manager in a Global Environment Map is NOT Threadsafe
--------------------------------------------------------------------
Key: JBRULES-2793
URL:
https://jira.jboss.org/browse/JBRULES-2793
Project: Drools
Issue Type: Bug
Security Level: Public(Everyone can see)
Affects Versions: 5.1.1.FINAL, FUTURE
Environment: N/A
Reporter: Anatoly Polinsky
Assignee: Mark Proctor
Labels: drools_persistence
Attachments: env.get.em.png
Original Estimate: 2 days
Remaining Estimate: 2 days
Currently persistence context / entity manager, once created, being placed to a global [
passed to almost every component ] 'Environment' map under
"XYZ_SCOPED_ENTITY_MANAGER" key.
In order to access this persistence context at runtime, all of the drools persistence
components follow the same pattern, which is just accessing the map:
e.g. EntityManager em = ( EntityManager ) env.get(
EnvironmentName.CMD_SCOPED_ENTITY_MANAGER );
While it works for a single threaded application [ a "playground" type of
application I assume ], it does not work in a multi-threaded environment. Simple example
would be:
one thread belongs to a transaction that is committed, which cleans up resources
on commit, including closing this "shared" entity manager
another thread grabs this entity manager from the "env" map, and throws
various exceptions, since a state of this entity manager ranges from being closed to
reopen ( e.g. by the third thread ), etc..
In general, Persistence Context live span should be as short as possible, hence bound to
a life span of a Transaction, which is actually normally thread bound. So in order to
access this Persistence Context from various Drools components, things like Transactions
and Threads need to be respected. This is how an entity manager can be accessed with
Spring's help:
EntityManagerFactory emf = ( EntityManagerFactory ) env.get(
EnvironmentName.ENTITY_MANAGER_FACTORY );
EntityManagerHolder emHolder = ( EntityManagerHolder )
TransactionSynchronizationManager.getResource( emf );
EntityManager em = emHolder.getEntityManager();
Granted Drools is aimed to provide integration with more than just Spring, but the above
example actually respects a current Transaction as well as a current Thread.
/Anatoly
P.S. Attached (PNG) is the list of files which use a "global" env map to access
"CMD_SCOPED_ENTITY_MANAGER", hence causing various concurrency problems. There
are more files that use an application scoped key, that can be found as easily.
--
This message is automatically generated by JIRA.
-
For more information on JIRA, see: