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?
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
// ...
}
}
.