KieSpringTransactionManager is a facade class used to interact with the platform transaction manager. It is ok to have many KieSpringTransactionManagers created in one logical transaction. The first KieSpringTransactionManager created in a transaction will create (via a KieSpringJpaManager or KieSpringTaskJpaManager) an ApplicationScopedEntityManager and the others will use that ApplicationScopedEntityManager. I have seen two different ways a KieSpringTransactionManager can be created, either from a SingleSessionCommandService or from a TaskTransactionInterceptor.
It is important that the ApplicationScopedEntityManager created gets cleaned up when the transaction commits. When a SingleSessionCommandService is created it will register a transaction synchronization to dispose itself. That dispose method ends up calling dispose on the KieSpringJpaManager, which will only clean up the EntityManager if it created the EntityManager.
I noticed that there are some ApplicationScopedEntityManagers that are created but never cleaned up! This could definitely lead to the issues we have been seeing. With further research I found that the EntityManager's that were created as ApplicationScopedEntityManagers for a KieSpringTaskJpaManager and never cleaned up were created as part of initializing the TaskTransactionInterceptor. The TaskTransactionInterceptor, like the SingleSessionCommandService, creates a KieSpringTransactionManager and registers a callback to clean up upon transaction completion. However, the TaskTransactionInterceptor only cleans up the commandBasedEntityManager.