Java Spring@Transactional注释属性优先级/继承

Java Spring@Transactional注释属性优先级/继承,java,spring,transactions,spring-transactions,Java,Spring,Transactions,Spring Transactions,在REQUIRED传播的情况下,当调用方方法本身是transactionnal时,如果事务属性不同,当前方法是否覆盖封闭的事务属性(例如rollboor) 说明: Class A { @Transactional(propagation = Propagation.REQUIRED, rollbackFor = { SomeException.class}) void foo() { try { b.bar();

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

说明:

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() {
        [...]
    }
}
编辑

好吧,我想避免琐碎的超出范围的答案,所以让我们明确一点,我知道spring传播处理

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

需要进行传播

当需要传播设置时,逻辑 事务作用域是为设置所基于的每个方法创建的 应用每个这样的逻辑事务范围都可以确定 使用外部事务作用域单独回滚状态 逻辑上独立于内部事务范围。属于 当然,对于标准的传播行为,所有这些 作用域将映射到同一物理事务。那么 内部事务作用域中设置的仅回滚标记不会影响 外部事务实际提交的机会(如您所料 是的

但是,在内部事务范围设置 仅回滚标记,外部事务尚未决定 回滚本身,因此回滚(由内部 事务范围)是意外的。相应的 此时将抛出UnexpectedRollbackException。这是意料之中的 使事务调用方永远不会被误导的行为 假设提交是在实际不执行的情况下执行的。所以如果 内部事务(外部调用方不知道)以静默方式进行 将事务标记为仅回滚,外部调用方仍然调用 犯罪外部调用方需要接收一个 UnexpectedRollbackException,用于清楚地指示已执行回滚 而是表演

我的问题可以改写为:

逻辑事务作用域是否包含事务属性?

请参阅的第16.5.7节。
即使在事务上下文中调用内部方法时使用REQUIRED对其进行注释,它也会映射到相同的物理事务。

根据我对规范的理解,在本例中我会说:

Class A {
    @Transactional(propagation = Propagation.REQUIRED,
        rollbackFor = { SomeException.class})
    void foo() {
        try {
           b.bar();
        } catch (OtherException e) {
           // the transaction is marked as rollback-only by the inner call as it thrown an OtherException
           // XXX --- or not if inner logical scope does not handle overridden property 'rollbackFor' ? ---
           // anyway, we avoid UnexpectedRollbackException by enforcing physical rollback to outter scope programmatically, by throwing :
           throw new SomeExeption(e);
        }
    }
}

Class B {
    @Transactional(propagation = Propagation.REQUIRED,
        rollbackFor = { OtherException.class})
    void bar() {
        [...]
    }
}
因此,我们可以将问题重新表述为:重写的“rollboor”属性是否由内部逻辑事务范围管理处理?


顺便问一下,您使用的事务管理器类和版本是什么?

因此,我设置了一个测试用例,简短的回答是肯定的

事务逻辑范围保存事务属性,其边界实际上是带注释的方法边界

因此,即使两个方法的底层物理事务相同,逻辑属性也适用于每个方法,并且内部方法可以强制回滚外部方法事务。 但是,如果最后一次触发提交,它将导致意外的回滚异常

参见Spring TransactionInterceptor(我的评论)

CompleteTransactionAfterhrowing():

AbstractPlatformTransactionManager.processRollback():


您可以使用多个Scenariory引用不同的传播,但您没有回答这个问题。注:如果使用调试器不信任内部变量状态,请明确调用getter TransactionSpectSupport.currentTransactionStatus().isRollbackOnly()引擎,以便在捕获后执行其他操作,你的抛弃方式很不方便
try {
        retVal = invocation.proceed();
}
catch (Throwable ex) {
        completeTransactionAfterThrowing(txInfo, ex);
        throw ex;
}
// txinfo is proper to the invocation target method
if (txInfo.transactionAttribute.rollbackOn(ex)) {
            try {
                txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
            }
else if (status.isNewTransaction()) { //requiresnew
    doRollback(status);
}
else if (status.hasTransaction()) { //requiered
        [...]
        doSetRollbackOnly(status);
    }
}