事务失效的几种原因

1、首先也是最重要的:

Java中的事务管理可以通过Spring框架提供的@Transactional注解来实现,这个注解位于Spring的相应包中。要确保事务功能有效,被@Transactional注解的方法必须是Spring IoC(Inversion of Control,控制反转)容器管理的一部分。这意味着:

  1. 方法所在类需要通过Spring注解如@Service@Repository@Component等注解进行标记,这样Spring会在启动时自动扫描并将其实例化为容器管理的Bean。

  2. 或者,如果使用XML配置的方式,对应的类或者方法需要在Spring配置文件中明确地作为<bean>元素定义,从而注册到Spring容器。

  3. 当一个方法被Spring容器管理后,其上的@Transactional注解才会被Spring AOP(面向切面编程)机制所识别,并通过代理模式实现事务的开启、提交或回滚等功能。

总之,要让一个事务生效,最基本的就是确保该方法是由Spring管理

但是,不一定是有spring注解的方法就一定可以被spring管理,比如下面这些情况就不会被Spring代理:

  1. 非public修饰符无法使用,因为非public修饰的方法无法被重写,也就不能被Spring代理。(另外有文章说springframework 6.0.11 开始支持project方法修饰)
  2. final方法不能使用,fina也是无法被重写,无法被代理。
  3. 静态方法不能使用,静态也是无法被重写,无法被代理。
  4. 类内部调用:事务是基于spring动态代理实现的,类内部调用方法会走java的代理,而不是spring的代理,故不会生效;

2、错误的设置了异常类型或者手动捕获了异常:

Transactional注解默认遇到运行时异常(RuntimeException)或者error会回滚,如果是sqlException或者IOExpection则不会回滚事务,阿里开发规约要求开发者指定异常类型,可以设置所有异常的父类Expection;另外自己捕获了异常或者抛出了其他非rollback定义的异常,此时系统会认为没有异常;

3、多线程导致的事务失效:

Transactional管理的事务是基于mysql(或其它数据库)的事务实现的,而mysql的事务只有拥有同一个数据库连接才能同时提交和回滚。如果在不同的线程,拿到的数据库连接是不一样的,所以是不同的事务,会导致事务失效。

如果确实需要在多线程下控制事务,

本来想自己写些Demo,但是看了网友 之乎者也·的文章,觉得写的太好了,就挂一个链接吧,链接详情:点击打开博客

  • 2
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值