java – Spring @Transactional Annotation属性优先级/继承

调用方法本身是transactionnal的情况下,当required传播时,如果它们不同,当前方法是否会覆盖封闭的事务属性(例如rollbackFor)?

插图:

Class A {
    @Transactional(propagation = Propagation.required,rollbackFor = { SomeException.class})
    void foo() {
        try {
           b.bar();
        } catch (OtherException e) {
           // is the transaction marked as rollback-only at this point ?
        }
    }
}

Class B {
    @Transactional(propagation = Propagation.required,rollbackFor = { OtherException.class})
    void bar() {
        [...]
    }
}

编辑:

好吧,我想避免琐碎的超出范围的答案,所以让我们清楚,我知道弹簧传播处理.

如果您不是,下面是文档的相关部分,我只想澄清有关上面示例的第一部分:

PROPAGATION_required

When the propagation setting is PROPAGATION_required,a logical
transaction scope is created for each method upon which the setting is
applied. Each such logical transaction scope can determine
rollback-only status individually,with an outer transaction scope
being logically independent from the inner transaction scope. Of
course,in case of standard PROPAGATION_required behavior,all these
scopes will be mapped to the same physical transaction. So a
rollback-only marker set in the inner transaction scope does affect
the outer transaction’s chance to actually commit (as you would expect
it to).

However,in the case where an inner transaction scope sets the
rollback-only marker,the outer transaction has not decided on the
rollback itself,and so the rollback (silently triggered by the inner
transaction scope) is unexpected. A corresponding
UnexpectedRollbackException is thrown at that point. This is expected
behavior so that the caller of a transaction can never be misled to
assume that a commit was performed when it really was not. So if an
inner transaction (of which the outer caller is not aware) silently
marks a transaction as rollback-only,the outer caller still calls
commit. The outer caller needs to receive an
UnexpectedRollbackException to indicate clearly that a rollback was
performed instead.

我的问题可以改写为:

逻辑事务范围是否包含事务属性

解决方法

所以,我设置了一个测试用例,简短的回答是肯定的.

事务逻辑范围包含事务属性,其边界确实是带注释的方法属性.

因此,即使两个方法的底层物理事务都相同,逻辑属性也适用于每个方法,而内部方法可以强制回滚外部方法事务.
如果最后一次触发提交,则会导致UnexpectedRollbackException.

比照Spring TransactionInterceptor(评论是我的)

try {
        retVal = invocation.proceed();
}
catch (Throwable ex) {
        completeTransactionAfterThrowing(txInfo,ex);
        throw ex;
}

completeTransactionAfterThrowing():

// txinfo is proper to the invocation target method
if (txInfo.transactionAttribute.rollbackOn(ex)) {
            try {
                txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
            }

AbstractPlatformTransactionManager.processRollback():

else if (status.isNewTransaction()) { //requiresnew
    doRollback(status);
}
else if (status.hasTransaction()) { //requiered
        [...]
        doSetRollbackOnly(status);
    }
}

相关文章

Java中的String是不可变对象 在面向对象及函数编程语言中,不...
String, StringBuffer 和 StringBuilder 可变性 String不可变...
序列化:把对象转换为字节序列的过程称为对象的序列化. 反序...
先说结论,是对象!可以继续往下看 数组是不是对象 什么是对...
为什么浮点数 float 或 double 运算的时候会有精度丢失的风险...
面试题引入 这里引申出一个经典问题,看下面代码 Integer a ...