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

薄洪涛2年前JAVA8576

事务失效的场景?

  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事务

相关文章

Ebean报错is not enhanced?

Ebean报错is not enhanced?

使用ebean的时候,会提示某个类没有enhanced,这里我们在idea中安装对应的plugin就可以了(需要看你的gradle的ebean版本)我的版本配置如下classpath("io...

谈谈你对IOC的理解

 ioc容器实际上就是个map(key,value),⾥⾯存的是各种对象(在xml⾥配置的bean节点、 @repository、@service、@controller、@componen...

设计模式之策略模式

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

jenkins部署maven项目

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

idea 如何导jar包

idea 如何导jar包

之前一直用的是ecplise,换成了idea后导包的操作就发生了变化,这篇文章详细说明下在idea中如何导入jar包首先在项目根目录建立lib文件夹,把你要导入的jar复制到lib目录下,如果是ecp...

基于dubbo改造现有http调用项目

使用zooker作为注册中心,将现有通过http调用的项目改造成dubbo调用公共项目规定接口public interface OrderService {  ...

评论列表

发表评论    

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