jakarta-eejpaejbjtaoc4j

Avoiding timeout on container-managed EntityManager


I have an J2EE application whose beans have container-managed EntityManager's. In long running method calls, trying to merge data throws a

RollbackException (Timed out)

I have tried using an EntityManagerFactory but it doesn't seem to be allowed:

Cannot use an EntityTransaction while using JTA

How can I run arbitrarily long processes without setting an unreasonable timeout? Can't JTA create a new transaction when needed?


Solution

  • Following the comments to my question, this question and the documentation here, I solved the problem using a container-managed EntityManager and TransactionAttributeType annotations.

    The bean method that caused the timeout now does multiple calls to a different method that handles a subtask, such as each method call executes within a different transaction. I use NOT_SUPPORTED attribute type since:

    If the client is not associated with a transaction, the container does not start a new transaction before running the method.

    With this arrangement, only the smaller processDoc method creates transactions that shouldn't timeout.

    public class MyBean {
        @EJB
        private DocsBean docsBean;
    
        /**
         * This method transaction risks a timeout
         * so no transaction is created with NOT_SUPPORTED
         */
        @TransactionAttribute(TransactionAttributeType.NOT_SUPPORTED)
        public void longRunning(List<Document> docs) {
            for (Document doc : docs) {
                // a different transaction is used for each element
                docsBean.processDoc(doc);
            }
        }
    }
    
    public class DocsBean {
        /** Runs within a new transaction */
        @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
        public void processDoc(Document document) {
            // takes some time but under the timeout
            // ...
        }
    }
    

    .