微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐