Warning: file_get_contents(/data/phpspider/zhask/data//catemap/9/java/332.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 如何捕获JTA事务内部抛出的异常?_Java_Spring_Jpa_Jta - Fatal编程技术网

Java 如何捕获JTA事务内部抛出的异常?

Java 如何捕获JTA事务内部抛出的异常?,java,spring,jpa,jta,Java,Spring,Jpa,Jta,我使用的是Spring 3.0.5、Hibernate 3.6.7和Atomikos Transactionessentials 3.7.0。使用applicationContext.xml中的AOP配置的事务。 一切正常。(提交、回滚) 我的意图是在jta事务中抛出一个特定的异常。 通过这种方式,应该回滚事务,我可以获得有关回滚原因的一些详细信息 问题是,我能捕捉到的唯一异常是atomikos抛出的回滚事务,它告诉我该事务被意外回滚 如何在事务之外获取自己的异常 这里有一个小例子,因为我不知道

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

我的意图是在jta事务中抛出一个特定的异常。 通过这种方式,应该回滚事务,我可以获得有关回滚原因的一些详细信息

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

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

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

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

声明要引发异常的方法的接口:

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向我指出了解决方案。事实上,我的事务并没有像我所怀疑的那样回滚,但由于我抛出异常的原因,我得到了一个违禁违规,因此atomikos在提交时抛出了它的异常。现在,我已将事务配置为回滚我的异常,所有操作都按照预期和期望的方式进行。

在抛出从Exception而不是MyException继承的MySpecialException时,我觉得这是一种类型


否则,捕获MySpecialException而不是MyException

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

如果抛出运行时异常,Spring默认回滚;如果抛出选中的异常,Spring默认提交

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


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

我已经说过,这只是一个示例,拼写错误不是问题所在。我真正的代码会编译并最终尝试捕获正确的异常(否则编译器会告诉我…)更正它…我不知道Atomikos,但他们是否会捕获您的异常并抛出自己的异常作为其原因?您是否分析了异常的getCause()方法的返回(从您的第二个捕获中)?是的,我详细查看了异常(在开发过程中不止一次),并尝试对其进行调试,但找不到任何东西。。。更新后可以提供堆栈跟踪和正在使用的框架版本吗?一些有趣的信息。通常,如果我遇到这样的异常,我会调试到atomikos中并找到真正的原因(例如一些hibernate或jdbc异常)。明天上午我将继续研究这个问题。。。。。我再也睁不开眼睛了。非常感谢。你救了我一天。我刚刚将我的异常更改为从RuntimeException继承,现在一切正常。我之前没有注意到,当我抛出自己的异常时,atomikos没有回滚,而且由于抛出异常,我昨天不知何故无法调试到atomikos中。
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
        }
    }
}