jpa事务失效的 场景

jpa默认只有抛出RuntimeException,才会回滚,

1.异常被捕获

//不回滚
    public void delete(String id) {
        try {
            ptInterInfoDao.deleteById(id);
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }

这个catch只是输出了异常信息,并没有抛出,不会发生回滚,要把异常抛出,才会回滚

//回滚
    public void delete(String id) {
        try {
            ptInterInfoDao.deleteById(id);
        } catch (Exception e) {
            System.out.println(e.getMessage());
            throw new RuntimeException(e.getMessage());
        }
    }

2. 方法不是public

@Transactional注解只有修饰public方法时,事务才会生效,如果用在非public方法上,如protected、private,事务将失效。

3. 没有被Spring管理

类上面没有spring的注解,意味着当前类没有被Spring管理,事务自然就失效了。

4. 异常类型错误

@Transactional注解中,回滚的默认异常是RuntimeException,由于在saveUser()方法中抛出异常不是RuntimeException,导致当前事务不会回滚。若要使事务生效,使用@Transactional(rollbackFor = Exception.class)指定类型。

@Service
public class UserServiceImpl implements UserService {
    
    @Transactional
    public void saveUser(User user){
     throw new Exception("save user error");
    }
}

5. 自身调用问题

@Transactional的实现原理是AOP,而AOP的实现原理是动态代理,自己调用自己的过程,并不存在代理对象的调用,这样
就不会产生AOP去为我们设置@Transactional配置的参数,这样就出现了自调用注解失效的问题。

@Service
public class Test3 {

    @Transactional
    public void test1(){
        test2();
    }

    public void test2(){
        System.out.println(1/0);
    }

}

解决方法:
把自己注入进来,然后通过注入的对象调用方法

@Service
public class Test3 {
    
    @Autowired
    Test3 test3;

    @Test
    public void test1(){
        test3.test2();
    }

    public void test2(){
        System.out.println(1/0);
    }

}

这个方法有个问题,就是如果你在引入了其它方法,他们都是空的,还可以使用工具类getBean获取对象
https://blog.csdn.net/a3562323/article/details/120862565?ops_request_misc=&request_id=f97a40296c354f5aaa031b80f489d675&biz_id=&utm_medium=distribute.pc_search_result.none-task-blog-2blogkoosearch~default-2-120862565-null-null.268v1control&utm_term=context&spm=1018.2226.3001.4450

6. 传播类型不支持事务,导致事务失效

/以非事务方式运行
@Transactional(propagation Propagation.NOT_SUPPORTED)

Propagation.NOT SUPPORTED:表示不以事务运行,当前若存在事务则挂起,都主动不支持以事务方式运行了,那事务肯定就不生效了

7. 多线程调用,导致事务失效

两个方法不在同一个线程中,获取到的数据库连接不一样,从而是两个不同的事务。我们说的同一个事务,其实是指同一个数据库连接,只有拥有同一个数据库连接才能同时提交和回滚。如果在不同的线程,拿到的数据库连接肯定是不一样的,所以是不同的事务。

已解决,多线程的事务
jpa多线程事务

8. 数据表本身是不支持事务,导致事务失效

在MYSQL 5.5 版本之前,Mysql 默认的数据引擎都是 MyISAM 的,而 MyISAM 是不支持事务的;在 5.5 版本之后,默认的数据引擎是 InnoDB 的,它是支持事务的,如果不是InnoDB ,需要手动修改成InnoDB

  • 0
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值