Mike Bockus
Mike Bockus

Reputation: 2079

How to rollback transactions and continue processing updates?

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

Answers (1)

esej
esej

Reputation: 3059

The call to processObjects are in a (separate) Transaction. You are catching all RuntimeExceptions, 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

Related Questions