jBPM 5.2, PostgreSQL 9.1.
Kris wrote (https://community.jboss.org/message/613360#613360) that session is thread safe. Well, getWorkItemManager() present in various implementations (e.g. CommandBasedStatefulKnowledgeSession) does not look particulary safe.
Anyway, my biggest issue is with SingleSessionCommandService. It uses *single* EntityManager instance to perform a database-related operations - see JpaPersistenceContextManaager#getApplicationScopedPersistenceContext, it returns the same (wrapped) appScopedEntityManager. Now, there are two scenarios wrt how SingleSessionCommandService#execute() can be called:
- there is no active JTA transaction,
- there is an active JTA transaction (e.g. the method is called from a business layer where someone already started a JTA transaction).
First one is not interesting - execute() will create a new transaction, do its work and commit the transaction. So far so good.
Second one means that in case of many threads calling SingleSessionCommandService#execute() at the same time the same connection will be used to perform many transactions *at the same time*. Now you can pick your favourite exception:
- org.postgresql.xa.PGXAException: Transaction interleaving not implemented (see http://jdbc.postgresql.org/documentation/faq.html#transaction-interleaving)
- org.hibernate.AssertionFailure - an assertion failure occured (this may indicate a bug in Hibernate, but is more likely due to unsafe use of the session)
- org.postgresql.xa.PGXAException: Connection is busy with another transaction
You can say that SingleSessionCommandService#execute() is synchronized but it does not help here. The commit (and the flush from EntityManager) happens elsewhere. Overall I think that SingleSessionCommandService is playing a very dangerous game in JTA managed environment. What is the rationale for *SingleSession*CommandService and PersistenceContextManager#getApplicationScopedPersistenceContext() anyway?
A simple test case attached, run few times or increase totalWorkers if you do not get exception at the first pass. If you want more standalone (e.g. Maven based) example let me know. A Spring-based simple web application can be provided as well.