栏目分类:
子分类:
返回
名师互学网用户登录
快速导航关闭
当前搜索
当前分类
子分类
实用工具
热门搜索
名师互学网 > IT > 软件开发 > 后端开发 > Java

Spring事务失效的几种情况

Java 更新时间: 发布时间: IT归档 最新发布 模块sitemap 名妆网 法律咨询 聚返吧 英语巴士网 伯小乐 网商动力

Spring事务失效的几种情况

原文链接:https://blog.csdn.net/hzj_java/article/details/113098631

1. 底层数据库引擎不支持事务

以MySQL为例,它有多种引擎,MyISAM引擎不支持事务操作,InnoDB引擎支持事务,MySQL从5.5.5开始默认的引擎是InnoDB,之前的版本默认的都是MyISAM,所以说如果是非常老的项目,这个需要考虑下。

2. 被@Transactional 注解修饰的方法为非public类型

如果被@Transactional注解修饰的方法,修饰符非public或者被final修饰,则事务会失效,因为AOP没办法为这样的方法生成一个代理,自然事务就无法生效。这个在Spring的官方文档里面也有说明。

在这个地方有个详细讨论过程:https://stackoverflow.com/questions/4396284/does-spring-transactional-attribute-work-on-a-private-method

3.异常被捕获了

如果异常被 catch 住,那事务也是会失效呢,伪代码如下:

@Transactional
public void test(){
  try{
    //插入一条数据
    insertA();
    //更改一条数据
    updateB();
  }catch(Exception e){
    log.error("异常被捕获了,事务就失效了",e);
  }
}
4,异常抛出类型错误

@Transactional 注解有个属性:rollbackFor,这个属性可以设置想要回滚的异常,那它默认的异常是什么?

不要犹豫直接告诉我答案,它默认回滚的是:RuntimeException,如果说我们没有设置这个属性,而且抛出的异常比这个大,那么事务就不会回滚,例如:

@Transactional
public void test(){
  try{
    //插入一条数据
    insertA();
    //更改一条数据
    updateB();
  }catch(Exception e){
    // 这个时候事务就不会回滚
    throw new Exception("操作失败!");
  }
}
5. 本类方法调用
@Service
public class TestServiceImpl implements TestService {

    public void testA() {
        // 查询数据,并进行一些判断
        // 调用另外一个方法
        testB();
    }
    
    @Transactional
    public void testB(Test test) {
        // update test
    }
}
@Service
public class TestServiceImpl implements TestService {

    @Transactional
    public void testA() {
        // 查询数据,并进行一些判断
        // 调用另外一个方法
        testB();
    }
    
    @Transactional(propagation = Propagation.REQUIRES_NEW)
    public void testB(Test test) {
        // update test
    }
}

testB() 方法上的事务是不管用的。

因为他们是本类方法直接调用,这个时候会用this关键字,没有经过 Spring 的代理类去调用此方法,从而没有开启事务管理,默认只有在外部调用事务才会生效。

所以说:加事务注解的方法给本类里面的方法调用,事务不生效!

有多种解决方法:

  • 最直白的就是把方法拆出来,放在两个类里面(Spring推荐的一种方式);
  • 在类里面注入自己,用注入的对象再调用另外一个方法,这个不太优雅;
  • 在Spring的配置里面增加一段配置:
6,没有被spring管理

当这个类只是一个普通类,没有被spring管理成为一个Bean对象,那它很自然的就不能使用spring提供的事务管理了,事务自然就不生效。例如:把@Service注解去掉,这个时候事务就不会生效,小伙伴们可以试试。

总结

以上列举了几种常见的事务失效的原因,其实发生最多就是异常被捕获了、异常抛出类型错误、本类方法调用不对这三个了,这三点只要在日常码代码的时候注意一下,基本就不会有问题了。

转载请注明:文章转载自 www.mshxw.com
本文地址:https://www.mshxw.com/it/345342.html
我们一直用心在做
关于我们 文章归档 网站地图 联系我们

版权所有 (c)2021-2022 MSHXW.COM

ICP备案号:晋ICP备2021003244-6号