spring中什么情况下事务会失效?

薄洪涛2年前JAVA8804

事务失效的场景?

  1. 权限问题,@Transactional 修饰的方法必须为public

  2. 方法用final修饰或者是static方法spring事务底层使用了aop,也就是通过jdk动态代理或者cglib,帮我们生成了代理类,在代理类中实现的事务功能。但如果某个方法用final修饰了,那么在它的代理类中,就无法重写该方法,而无法添加事务功能。

  3. 方法内部调用 如果在某个Service类的某个方法中,调用另外一个事务方法,即在同一个类中的方法直接内部调用,事务会失效。m1中通过this的方式调用了m2方法,而this并不是代理对象,this.m2()不会被事务拦截器,所以事务是无效的

	@Component
	public class UserService {
	    public void m1(){
	        this.m2();
	    }
	    
	    @Transactional
	    public void m2(){
	        //执行db操作
	    }
	}

如果外部直接调用通过UserService这个bean来调用m2方法,事务是有效的,上面代码可以做一下调整,如下,在UserService中注入了自己(或者在该Service类中使用AopContext.currentProxy()获取代理对象),此时m1中的m2事务是生效的

@Component
public class UserService {
    @Autowired //这里注入了自己
    private UserService userService;

    public void m1() {
        this.userService.m2();
    }

    @Transactional
    public void m2() {
        //执行db操作
    }
}
  1. 未被spring容器管理 使用spring事务的前提是:对象要被spring管理,需要创建bean实例。通常情况下,我们通过@Controller、@Service、@Component、@Repository等注解,可以自动实现bean实例化和依赖注入的功能。如果类未被 Spring 管理,事务自然就失效了。

  2. 多线程调用 spring的事务是通过数据库连接来实现的。当前线程中保存了一个map,key是数据源,value是数据库连接。我们说的同一个事务,其实是指同一个数据库连接,只有拥有同一个数据库连接才能同时提交和回滚。如果在不同的线程,拿到的数据库连接肯定是不一样的,所以是不同的事务

  3. 异常情况 默认情况下,RuntimeException和Error的情况下,spring事务才会回滚。
    通过try catch把异常捕获到处理了也不会回滚。


标签: JAVA事务

相关文章

设计模式之策略模式

在开始之前,我们先看一下一个令人不爽的写法if ($k == 0) {   // do something } ...

ebean相关的查询

where// select * from user where name = "boht"List...

java相关日期函数

java相关日期函数

JDK7Data// 1.创建当前时间 Date d1 = new Date(); System.out.println(d1); // ...

centos安装java环境

centos安装java环境

很多工具(比如Lucene )都要依赖java环境,所以我在服务器上装了一个jdk,然后在这篇文章中记录下安装的步骤;当我们修改程序并通过SVN上传到服务器后环境:  &...

接口熔断器resilience4j的使用

pom引入<!-- 熔断器 : https://mvnrepository.com/artifact/io.github.resilience4j/resilien...

jenkins部署maven项目

1. 环境配置jenkins安装 Maven Integration plugin插件配置maven,java等路径2. 2.新建item,选择构建maven项目a. 2.1 源码管理填入git地址、...

评论列表

发表评论    

◎欢迎参与讨论,请在这里发表您的看法、交流您的观点。