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

标签 java spring jpa jta

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

我的意图是在 jta 事务中抛出一个特定的异常。 这样事务应该被回滚,我得到一些关于回滚原因的详细信息。

问题是,我能捕捉到的唯一异常是 atomikos 抛出的回滚事务,它告诉我事务被意外回滚。

如何在事务之外获取自己的异常?

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

一个特定的异常(exception)(也可能是一些标准的异常(exception)):

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

一个接口(interface)声明了一个声明抛出异常的方法:

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

实现接口(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
    }
}

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

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 向我指出了解决方案。事实上,我的交易没有像我怀疑的那样回滚,但是由于我抛出异常的原因,我遇到了约束违规,因此 atomikos 在提交时抛出了它的异常。现在,我已将我的事务配置为针对我的异常进行回滚,一切都按预期和需要进行。

最佳答案

你的异常是运行时异常还是检查异常?

如果抛出运行时异常,Spring 默认回滚,如果抛出检查异常,则默认提交。

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

因此,如果您希望此异常导致回滚,请将其设为运行时异常或在@Transactional 注释的rollbackFor 属性中声明它。如果一定不能导致回滚,则尝试找出 Atomikos 拒绝提交的原因(超时太短,其他……日志可能会有所帮助)。

关于java - 如何捕获 JTA-Transaction 中抛出的异常?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/9421082/

相关文章:

java - Vaadin Spring 中的 MVP 结构

java - 使用谓词查询数据并使用 Spring Data JPA 进行分页

java - 使用 AttributeConverter 转换为 UUID 导致 'No Dialect mapping for JDBC type' 异常

java - 什么时候以及为什么我们必须实现 Comparable 接口(interface)?

java - 为什么我的代码中会间歇性地发生死锁?

java - 如何在android中的ExpandableListView中添加三级ListView

spring - 我如何找出我的 session 试图序列化的对象?

java - 用java计算组合

spring - 如何在 JPA Criteria API 中为 @ManyToOne 关联组合 DISTINCT 和 ORDER BY?

java - Spring如何管理映射表(多对多)