Reputation: 2079
I'm trying to wrap my head around transaction management, but I'm having a hard time figuring out how I should recover from a transaction rollback and continue committing new transactions. The code below is a simplified version of what I'm trying to do:
@Stateless
public class MyStatelessBean1 implements MyStatelessLocal1 {
@EJB
private MyStatelessLocal1 myBean1;
@TransationAttribute(TransactionAttributeType.NEVER)
public void processObjects(List<Object> objs) {
// this method just processes the data; no need for a transaction
for(Object obj : objs) {
// If the call to process results in the transaction being rolled back,
// how do I rollback the transaction and continue to iterate over objs?
this.myBean1.process(obj);
}
}
@TransationAttribute(TransactionAttributeType.REQUIRES_NEW)
public void process(Object obj) {
// do some work with obj that must be in the scope of a transaction
}
}
If a transaction rollback occurs in the call to process(Object obj)
, then an exception is thrown and the rest of the Objects in objs
are not iterated over and no updates are committed. If I want to rollback the transactions where an error occurs, but continue to iterate over the objs
List, how should I go about doing that? If I just catch the exception like in the code below, is there anything I need to do to make sure the transaction is rolled back?
public void processObjects(List<Object> objs) {
// this method just processes the data; no need for a transaction
for(Object obj : objs) {
// If the call to process results in the transaction being rolled back,
// how do I rollback the transaction and continue to iterate over objs?
try {
this.myBean1.process(obj);
} catch(RuntimeException e) {
// Do I need to do anything here to clean up the transaction before continuing to iterate over the objs?
}
}
}
Upvotes: 4
Views: 4776
Reputation: 3059
The call to processObjects are in a (separate) Transaction.
You are catching all RuntimeException
s, lets divide those exceptions into two groups.
Group one:
EJBException
or any other exception annotated with @ApplicationException(rollback=true)
->
The container will rollback that exception for you.
Group two: All other exceptions. (Basically those exceptions that won't be rolledback automatically by the container :( ). -> The transaction won't be rolledback unless you make it so.
To force a rollback you can always throw new EJBException
... etc ...
Also, please note that once an Exception annotated with @ApplicationException(rollback=true)
is thrown, the container will rollback the current transaction, if there is one (EJB-Beans are in a transaction by default) no matter what you do (catch and ignore for example) if the Bean is annotated with @TransactionManagement(TransactionManagementType.CONTAINER)
which is default in EJB.
Upvotes: 3