Hi, [1] is an example of how the WildFly JPA container is ensuring that the background (transaction manager) reaper (transaction timeout) thread does not cause EntityManager.close() to be called, while the application is actively executing calls to EntityManager.*().
The idea, as suggested by Tom Jenkinson, is to track when the application (container) calls transaction.commit/rollback. We also register a Synchronization. When we detect that transaction.commit/rollback and the Synchronization.afterCompletion have both been called, it is safe to perform the EntityManager clean up action, as we know that only one thread will then be invoking the EntityManager.close(). >From a state point of view, please look at how [2] is checking for the EventType.DISASSOCIATING event, which means that transaction.rollback/commit was called by the application. If the Synchronization.afterCompletion has already run as well, then we clean up the EntityManager, otherwise, we defer the cleanup action until the call to Synchronization.afterCompletion occurs. Also see [3] which contains the recommendation of using the above solution. Scott [1] https://github.com/wildfly/wildfly/blob/master/jpa/subsystem/src/main/java/org/jboss/as/jpa/transaction/TransactionUtil.java#L146 [2] https://github.com/wildfly/wildfly/blob/master/jpa/subsystem/src/main/java/org/jboss/as/jpa/transaction/TransactionUtil.java#L197 [3] https://developer.jboss.org/message/919807 _______________________________________________ hibernate-dev mailing list hibernate-dev@lists.jboss.org https://lists.jboss.org/mailman/listinfo/hibernate-dev