spring中事务的原理

发布时间 2023-04-10 17:55:56作者: 毛毛雨1997

背景

spring在使用事务的时候会出现事务失效的情况。这里了解spring中事务原理,以及事务失效的原理和解决方案。

原因

spring中事务是基于AOP的,如果不是代理对象执行的话就不会有事务。

比如,加上 @Transactional 的事务方法,是被包裹起来的。

public class UserServiceProxy extends UserService {

	UserService target;

	public void test() {
		// 切面逻辑 spring transaction
		// 有 @Transactional 则开启事务

		target.test();

		// 1. 事务管理器新建一个数据库连接 conn
		// 2. 数据库连接的 autocommit 设置位 false conn.autocommit = false;
		// jdbcTemplate 会获取到前面建立的数据库连接
		// 执行SQL
		// 调用连接到 commit 方法提交事务 conn.commit();
		// 如果失败,就调用连接的 rollback 进行回滚

	}


}
    @Transactional  
   public void testTransactionManager() {  
      jdbcTemplate.execute("INSERT INTO `demo_db`.`x_sys_tb_user`(`user_id`, `user_name`) VALUES ('1', '1');");  
      subA();  
   }  
  
   // propagation 传播  
   // 设置传播类型  
   @Transactional(propagation = Propagation.NEVER)  
   public void subA() {  
      jdbcTemplate.execute("INSERT INTO `demo_db`.`x_sys_tb_user`(`user_id`, `user_name`) VALUES ('2', '2');");  
   }

在执行 testTransactionManager() 的时候 ,subA();是 target即普通对象执行的。

事务生效解决办法

  1. 拆分,把失效的事务拆分出去。新建一个对象把失效的事务方法放到这个对象中,然后注入这对象,
  2. 自己注入自己(注:在 spring 中也算是循环依赖,但是 spring 帮我们解决了)
  3. AopContext.currentProxy() 获取当前的代理对象,然后用代理对象调用失效的事务(注:这种方法可能可读性差一点)