简体   繁体   中英

How to catch a exception thrown inside of a JTA-Transaction?

I'm using Spring 3.0.5, Hibernate 3.6.7 and Atomikos Transactionessentials 3.7.0. Transactions configured using AOP in applicationContext.xml. Everything just works fine. (commit, rollback)

My intention is to throw a specific exception inside of a jta-transaction. This way the transaction should be rolled back and I get some detailed information about the cause of the rollback.

The problem is, that the only exception I can catch is a rollback-transaction thrown by atomikos, telling me, that the transaction was unexpectedly rolled back.

How can I get my own exception outside the transaction?

Here is a small example, because I don't know if my explanation was good enough. This is only for demonstration what my intention is. Please don't comment any typos.

A specific exception (might be some standard exception as well):

public class MySpecialException extends Exception {
    public MySpecialException(String someInfo) {
        super(someInfo);
    }
}

An interface declareing a method which declares to throw the exception:

public interface MyInterface {
    Object someJtaTransactionMethod(String param) throws MySpecialException;
}

A class implementing the interface:

public class MyClass implements MyInterface {
    Object someJtaTransactionMethod(String param) throws MySpecialException {

        // some operations with some errorstate detected
        // so throw the exception:
        throw new MySpecialException("Things went terribly wrong!");

        // some other code
    }
}

And some code that calls the function and catches the exceptions.

public class Caller {

    @Autowired
    private MyInterface callee;

    public void test() {
        try {
            callee.someJtaTransactionMethod("Some test");
        } catch (MySpecialException mex) {
            // I want to get here
        } catch (Exception ex) {
            // but I only get here
        }
    }
}

Is this possible at all?

UPDATE: Of course I had a look at the exception cause. The exception itself is of org.springframework.transaction.UnexpectedRollbackException. The cause is of class javax.transaction.RollbackTransaction and has a cause com.atomikos.icatch.RollbackException.

I think what happens is, that atomikos notices the exception and performs a rollback (as desired), but then atomikos (maybe other jta-implementations as well) throws an exception indicating that the transaction was rolled back (unexpectedly) and my exception is gone.

UPDATE 2: Funny thing is, that if I haven't done anything that has to be rolledback, I can catch my exception as desired!

UPDATE 3 and SOLUTION: JB Nizet pointed me to the solution. In fact my transaction wasN#t rolled back as I suspected, but because of the reason for me to throw my exception, I got an contraint violation and thus atomikos threw its exception on commit. Now that I configured my transaction to rollback for my exceptions everything works as expected and desired.

Is your exception a runtime exception or a checked exception?

Spring rollbacks by default if a runtime exception is thrown, and commits by default if a checked exception is thrown.

From the stack trace, it seems that your exception is a checked exception, so Spring tries to commit, but can't because the JTA TM (Atomikos) refuses to commit (because of a timeout, for example).

So, if you want this exception to cause a rollback, make it a runtime exception or declare it in the rollbackFor attribute of the @Transactional annotation. If it must not cause a rollback, then try to discover why Atomikos refuses to commit (too short timeout, something else... the logs could help).

Looks like a type to me as you throw a MySpecialException that inherits from Exception instead of MyException?

Otherwise catch MySpecialException instead of MyException.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM