首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >Spring @事务性注释属性优先/继承

Spring @事务性注释属性优先/继承
EN

Stack Overflow用户
提问于 2015-10-22 09:22:37
回答 3查看 5.2K关注 0票数 8

REQUIRED传播的情况下,当调用方方法本身是事务处理时,如果它们不同,当前方法是否覆盖包围事务属性(例如rollbackFor)?

说明:

代码语言:javascript
复制
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 当传播设置为PROPAGATION_REQUIRED时,将为应用该设置的每个方法创建一个逻辑事务范围。每个这样的逻辑事务作用域都可以单独确定回滚状态,外部事务作用域在逻辑上独立于内部事务范围。当然,对于标准的PROPAGATION_REQUIRED行为,所有这些作用域都将映射到相同的物理事务。因此,内部事务范围中设置的仅回滚标记确实会影响外部事务实际提交的机会(正如您预期的那样)。 但是,在内部事务作用域设置仅回滚标记的情况下,外部事务尚未决定回滚本身,因此回滚(由内部事务范围悄悄触发)是意外的。在这一点上抛出相应的UnexpectedRollbackException。这是预期的行为,这样事务的调用方就不会被误导,以为提交是在没有执行的情况下执行的。因此,如果内部事务(外部调用方不知道)静默地将事务标记为仅回滚,则外部调用方仍然调用commit。外部调用方需要接收一个UnexpectedRollbackException,以清楚地指示已执行回滚。

我的问题可以改写如下:

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

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2015-10-27 13:57:07

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

事务逻辑作用域保存事务属性,其边界实际上是带注释的方法。

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

请参阅Spring TransactionInterceptor (评论是我的)

代码语言:javascript
复制
try {
        retVal = invocation.proceed();
}
catch (Throwable ex) {
        completeTransactionAfterThrowing(txInfo, ex);
        throw ex;
}

completeTransactionAfterThrowing():

代码语言:javascript
复制
// txinfo is proper to the invocation target method
if (txInfo.transactionAttribute.rollbackOn(ex)) {
            try {
                txInfo.getTransactionManager().rollback(txInfo.getTransactionStatus());
            }

AbstractPlatformTransactionManager.processRollback():

代码语言:javascript
复制
else if (status.isNewTransaction()) { //requiresnew
    doRollback(status);
}
else if (status.hasTransaction()) { //requiered
        [...]
        doSetRollbackOnly(status);
    }
}
票数 2
EN

Stack Overflow用户

发布于 2015-10-27 10:07:55

根据我对规范的理解,我想在这个例子中说:

代码语言:javascript
复制
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() {
        [...]
    }
}

因此,我们可以将问题重新表述为:是否被覆盖的"rollbackFor“属性由内部逻辑事务范围管理?处理?

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

票数 0
EN

Stack Overflow用户

发布于 2015-10-22 09:36:31

参见春季文献 16.5.7节。即使在事务上下文中调用内部方法时需要对其进行注释,但它将映射到相同的物理事务。

票数 -1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/33277563

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档