Search code examples
jbossjava-ee-6jboss7.x

Java EE6 (with JBoss7): automatically roll back the transaction


I want to test the automatically rolling back of an transaction. Therefore, I implemented a simple bean[src] that throws an system exception which should result in an automatically roll back[1]. I also implemented the interface SessionSynchronization so I can affect the rollback with the method afterCompletion. But the argument of this method is true which I expect to be false in regards to the specs[2].

Am I missing something or is this a bug in JBoss 7? I already searched the bug tracker but did not find anything ... maybe I used the wrong words?

If this is not a bug: are there any settings regarding to set the afterCompletion parameter to false if a system or an application exception occures?


[1]: "There are two ways to roll back a container-managed transaction. First, if a system exception is thrown, the container will automatically roll back the transaction. Second, by invoking the setRollbackOnly method of the EJBContext interface, the bean method instructs the container to roll back the transaction. If the bean throws an application exception, the rollback is not automatic but can be initiated by a call to setRollbackOnly." http://docs.oracle.com/javaee/6/tutorial/doc/bncij.html

[2]: "The afterCompletion method notifies a stateful session bean instance that a transaction commit protocol has completed, and tells the instance whether the transaction has been committed or rolled back." http://docs.oracle.com/javaee/6/api/javax/ejb/SessionSynchronization.html

[src]:

@Stateful
@LocalBean
public class RollbackTestBean implements RollbackTest, SessionSynchronization {

  int counter = 0;
  int counterBuffer = 0;
  private final Logger logger = Logger.getLogger(this.getClass().getName());

  @Override
  public int getCounter() {
    return counter;
  }

  @Override
  public void throwSystemException() throws SystemException {
    counter++;
    throw new SystemException();
  }

  @Override
  public void afterBegin() throws EJBException, RemoteException {
    logger.info("[TX]: after begin");
    counterBuffer = counter;
  }

  @Override
  public void afterCompletion(boolean success) throws EJBException, RemoteException {
    logger.info("[TX]: after completion: " + success);
    if (!success)
      counter = counterBuffer;
  }

  @Override
  public void beforeCompletion() throws EJBException, RemoteException {
    logger.info("[TX]: before completion");
  }
}

Solution

  • There are two SystemExceptions

    org.omg.CORBA.SystemException  subclass of RuntimeException
    javax.transaction.SystemException subclass of Exception
    

    I hope you are using org.omg.CORBA.SystemException

    EJB3.1 spec says, if its RuntimeException or ApplicationException, the transaction needs to be rolled back.

    As far as I can see, ApplcationException is handled correctly in JBoss 7.1.1, but not RuntimeException.

    With RuntimeException, there is a similar issue reported when remove() is called on Statefull bean, reference here. I am getting the same error message when I try to throw RuntimeException. Its fixed in Verion 7.1.3 I think. But I have not tested myself.

    You can try 7.1.3, if you are looking for a fix. If you have your Exception and wants transaction rollback, use

    @ApplicationException(rollback=true)
    

    Maddy