Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

EJB: Avoid Transaction rollback

Tags:

When a (transactional) method of an EJB calls another (transactional) method of another EJB, and an exception is thrown in the second, but catched in the first one, it seems that the transaction is automatically rolled back when the second one returns, even if the first one catches it, is this true? how can I avoid it?

The scenario is the following one:

@Stateless
class ClassA {
   @EJB
   ClassB objectB;

   methodA() { 
       try { 
            objectB.methodB(); 
       }
       catch(Exception e) {
            //Here the transaction started in this method is 
            //automatically rolled back. Is this avoidable?
       } 
   }
}

@Stateless
class ClassB {
   methodB() throws Exception { throw new Exception() }
}
like image 728
Mr.Eddart Avatar asked Dec 13 '11 14:12

Mr.Eddart


People also ask

What is transaction rollback exception?

javax.transaction RollbackException exception is thrown when the transaction has been marked for rollback only or the transaction has been rolled back instead of committed. This is a local exception thrown by methods in the UserTransaction , Transaction , and TransactionManager interfaces.

How EJB transaction works?

EJB Container/Servers are transaction servers and handles transactions context propagation and distributed transactions. Transactions can be managed by the container or by custom code handling in bean's code. Container Managed Transactions − In this type, the container manages the transaction states.

What is transaction attribute in EJB?

A transaction attribute controls the scope of a transaction. Figure 28–1 illustrates why controlling the scope is important. In the diagram, method-A begins a transaction and then invokes method-B of Bean-2 .


1 Answers

Transaction is rolled back in case you throw a RuntimeException or any Exception which have @ApplicationException annotation with rollback attribute set to true, so:

@ApplicationException(rollback=true)
public class MyException extends Exception {
    // ...
}

will rollback the current transaction.

By default ApplicationException doesn't rollback your transaction.

If you don't want to methodB to rollback your transaction you can either change the rollback behavior of your ApplicationException or prevent the transaction sharing.

The latter is achievable by changing the TransactionAttribute of methodB i.e. to RequiresNew. Then methodA transaction (Tx1) will be suspendend and in case methodB throws an exception which results in rollback of its transaction (Tx2), you can still catch it in methodA and prevent rollback of your methodA transaction (Tx1).

like image 139
Piotr Nowicki Avatar answered Oct 10 '22 19:10

Piotr Nowicki