美文网首页
@Transactional失效场景

@Transactional失效场景

作者: 玖柒叁 | 来源:发表于2023-09-11 10:43 被阅读0次

    失效场景汇总

    image.png

    使用@Transactional要注意以下几个问题:数据库引擎是否支持事务、Spring中是否配置开启@Transactional事务、propgation设置错误、rollbackFor设置错误、catch的时候吞了异常、在同类中的普通方法调用事务方法、事务方法不是public的。

    失效场景详述

    底层是否支持

    数据库引擎是否支持事务

    使用事务首先要确认自己选择的数据库引擎是否支持事务,如现在大部分公司选择的MySQL的innodb引擎是支持事务的

    配置是否正确

    Spring中是否配置开启@Transactional事务

    @EnableTransactionManagement开启注解版本事务功能

    propgation设置错误

    propgation定义了@Transactional的边界:是否使用事务、在存在事务时如何表现
    事务的传播机制如下所示:
    Propagation.REQUIRED:如果当前存在事务,则使用该事务。 如果当前没有事务,则创建一个新的事务。
    Propagation.REQUIRES_NEW:创建一个新的事务,如果当前有事务,暂停当前的事务。
    Propagation.SUPPORTS:如果当前存在事务,则加入该事务;如果当前不存在事务,则以非事务的方式继续运行
    Propagation.MANDATORY:如果当前存在事务,则加入该事务;如果当前不存在事务,则抛出异常
    Propagation.NOT_SUPPORTED:以非事务的方式运行,如果当前存在事务,暂停当前的事务。
    Propagation.NEVER:以非事务的方式运行,如果当前存在事务,则抛出异常。
    Propagation.NESTED:如果当前存在事务,则创建一个嵌套事务来运行,如果当前没有事务,行为等同于PROPAGATION_REQUIRED

    rollbackFor设置错误

    定义了在抛出什么样的异常时事务会进行回滚。Spring默认抛出了未检查unchecked异常(继承自 RuntimeException 的异常)或者 Error才回滚事务。

    代码是不是合理

    catch的时候吞了异常

    如果想要spring事务能够正常回滚,必须抛出它能够处理的异常。如果没有抛异常,则spring认为程序是正常的

    在同类中的普通方法调用事务方法

    @Transactional事务主要是利用springAOP生产代理对象,然后用代理对象来进行事务的提交,在使用JDK的动态代理时,代理类在处理完增强逻辑后通过反射调用了目标类的原始方法,之后便是直接在该原始方法里面执行逻辑,如果代理类最初调用的是一个普通的方法,那么调用该方法之前并没有进行增强,而后所有的逻辑都在目标类中执行,因此即使此时在目标类中调用了事务方法其实也并没有进行代理。因此事务会失效。

    事务方法不是public的

    在生成代理类时,如果注解的方法不是public的话,会导致事务失效,原因是在AbstractFallbackTransactionAttributeSource类的computeTransactionAttribute方法中有个判断,如果目标方法不是public,则TransactionAttribute返回null,即不支持事务

    参考文章

    事务失效的6种场景
    事务失效的12种场景

    相关文章

      网友评论

          本文标题:@Transactional失效场景

          本文链接:https://www.haomeiwen.com/subject/fgksvdtx.html