当前位置: 首页 > 知识库问答 >
问题:

子函数中的RuntimeException应该不会影响父调用函数REQUIRES _ NEW有作用吗?

甘西岭
2023-03-14

我正在使用一个 html" target="_blank">DB2 数据库并测试了以下代码:无论方法 B 是否Propagation.REQUIRES_NEW,如果方法 B 有异常,则无论如何,方法 A 的结果都将正确提交。

这与我的假设相反,即必须使用Propagation.REQUIRES_NEW来实现这一目标。

        ClassA
            @Autowire
            private ClassB classB;

            @Transactional
            methodA(){
                ...
                try{
                     classB.methodB();
                }catch(RuntimeException ex){
                     handleException(ex);
                }
                ...
            }

        ClassB
            @Transactional(propagation = Propagation.REQUIRES_NEW)
            methodB(){...}

谢谢你@Kayaman我想我现在已经想通了。

我看到的行为是因为methodB的@Transactional注释不起作用,所以methodB被视为没有任何事务注释的普通函数。

它出错的地方是,在方法A中,我通过super.methodB()从ClassB的子类中调用方法B,并认为它会给出一个事务方法B,它不起作用:

    @Service
    @Primary
    ClassC extends ClassB{
        @override
        methodB(){
            super.methodB();
        }
    }

我知道,如果从同一类的另一个非事务性方法调用事务方法,事务注释将不起作用。

不知道超级.methodB()也会因为同样的原因而失败(任何人都可以给出更多的解释吗?

总之,在第一个代码块的示例中,当方法B具有RuntimeException时,

如果methodB具有< code>NO transaction批注:A

如果方法B具有REQUIRED注释:A

如果methodB具有< code>REQUIRES_NEW批注:A

共有1个答案

慕嘉运
2023-03-14

如果不使用< code>REQUIRES_NEW(即默认的< code>REQUIRED或其他类似的方式),< code>ClassB.methodB()参与与< code>ClassA.methodA()相同的事务。in methodB()中的异常将同一事务标记为回滚。即使捕获到异常,事务也将被回滚。

使用REQUIRES_NEW,回滚的事务将特定于methodB()

ClassA
@Transactional
methodA(){
    try{
         classB.methodB();
    }catch(RuntimeException ex){
         handleException(ex);
    }
}

ClassB
@Transactional
methodB(){
    throw new RuntimeException();
}

上面的代码将回滚整个事务。使用传播=TransactionPropagation.REQUIRES_NEW用于方法B()它不会。

如果没有方法B()的任何注释,在方法A()级别只有一个tx边界,Spring不会意识到抛出了异常,因为它被捕获在方法的中间。这类似于将methodB()的内容内联到methodA()。如果该异常是非数据库异常(例如NullPointerException),则事务将正常提交。如果该异常是数据库异常,则底层数据库事务被设置为回滚,但Spring没有意识到这一点。然后,Spring尝试提交,并抛出UnexpectedRollbackException,因为数据库不允许提交tx。

显式或意外地忽略注释是错误的。如果要执行数据库操作,必须使用定义良好的事务上下文,并了解传播。

调用super.methodB()绕过了Spring的正常代理机制,所以即使有注释,它也被忽略了。最后,调用super.methodB()对我来说似乎是一种设计气味。使用继承来减少行数通常是不好的做法,在这种情况下会导致严重的错误。

 类似资料:
  • 我有一个简单的firebase functions脚本设置(运行firebase admin 8.0版和firebase functions 2.3.1版): 该函数的目标只是返回用户的IP地址。它在函数控制台中记录良好,没有错误。 这是客户端代码: 但是,控制台表示“result”不是有效的JSON对象。 我尝试过使用互联网上其他人推荐的https.on呼叫,但是,控制台说该功能不存在。 任何帮

  • 我用这篇文章作为例子(React way),但它对我不起作用。请指出我的错误,因为我不明白出了什么问题。 这就是我看到的错误: 错误:this.props.on点击不是一个函数 这是我的密码: 提前谢谢!

  • 本文向大家介绍使用匿名函数会影响性能吗?,包括了使用匿名函数会影响性能吗?的使用技巧和注意事项,需要的朋友参考一下 从某种意义上说,使用匿名函数会影响性能,您需要在每次迭代时创建一个新的函数对象。匿名函数始终使用变量名加载。顾名思义,匿名允许创建没有任何名称标识符的函数。它可以用作其他函数的参数。使用变量名调用它们- 示例 这就是可以使用JavaScript匿名函数的方式- 这是一个例子-

  • 如果我使用CreateCriteria()函数添加了一个条件限制。限制是否将保存在数据库中?提前谢谢!..

  • 问题内容: 我知道都存在一些类似的问题,但是我很难理解今天对这个问题的正确想法并将其推断出我的处境。 我有一个简单的应用程序,ScoreBox有一个ScoreList,其中包含很多分数。我想让Score onClick调用ScoreList handleScoreRemove。我正在显示完整的js文件,但最重要的行是第5行和第77行。 问题答案: 你需要通过 并在组件中这样称呼它