如何捕获JTA-Transaction中抛出的异常?

时间:2012-02-23 20:50:54

标签: java spring jpa jta

我正在使用Spring 3.0.5,Hibernate 3.6.7和Atomikos Transactionessentials 3.7.0。在applicationContext.xml中使用AOP配置的事务。 一切都很好。 (提交,回滚)

我的目的是在jta-transaction中抛出一个特定的异常。 这样就可以回滚事务,并获得有关回滚原因的一些详细信息。

问题是,我可以捕获的唯一例外是atomikos抛出的回滚事务,告诉我,事务意外地被回滚。

如何在交易之外获得自己的异常?

这是一个小例子,因为我不知道我的解释是否足够好。 这只是为了证明我的意图。请不要评论任何拼写错误。

特定异常(也可能是某些标准异常):

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

声明一个声明抛出异常的方法的接口:

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

实现接口的类:

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
    }
}

一些代码调用函数并捕获异常。

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
        }
    }
}

这有可能吗?

更新:我当然看看异常原因。异常本身是org.springframework.transaction.UnexpectedRollbackException。原因是类javax.transaction.RollbackTransaction,并且有一个原因com.atomikos.icatch.RollbackException。

我认为发生的事情是,atomikos注意到异常并执行回滚(根据需要),但是然后atomikos(也许是其他jta实现)抛出异常,指示事务已回滚(意外)并且我的例外消失了。

更新2:有趣的是,如果我没有做任何必须回滚的事情,我可以根据需要抓住我的例外情况!

更新3和解决方案:JB Nizet向我指出了解决方案。实际上我的事务是按照我的怀疑回复了N#t,但由于我抛出异常的原因,我得到了一个违规行为,因此atomikos在提交时抛出了它的异常。现在我将事务配置为回滚以查找异常,一切都按预期和期望工作。

2 个答案:

答案 0 :(得分:4)

您的异常是运行时异常还是已检查异常?

默认情况下,如果抛出运行时异常,则返回Spring回滚,如果抛出已检查的异常,则默认提交。

从堆栈跟踪看来,您的异常似乎是一个已检查的异常,因此Spring尝试提交,但不能,因为JTA TM(Atomikos)拒绝提交(例如,因为超时)。

因此,如果您希望此异常导致回滚,请将其设置为运行时异常,或者在@Transactional批注的rollbackFor属性中声明它。如果它不能导致回滚,那么试着发现为什么Atomikos拒绝提交(超时太短,其他东西......日志可以帮助)。

答案 1 :(得分:0)

当你抛出一个继承自Exception而不是MyException的MySpecialException时,看起来像是一个类型?

否则捕获MySpecialException而不是MyException。