Spring 使用私有方法引导事务传播

Spring Boot transaction propagation with private Methods

据我了解,私有方法不能在 Spring Boot.因此 @Transactional 不能放在私有方法上。这让我想知道,如果中间有一个或多个私有方法,事务可以传播吗?以下代码块是否等效:

class SomeClass{

@Autowired Dao dao;
 
@Transactional(propagation = Propagation.REQUIRED)
public bigMethod(int someArgument){
  Data data1 = process(someArgument);
  Data data2 = process(someArgument+1);
  this.dao.save(data1);
  this.dao.save(data2);
}

}

上面是否等同于:

class SomeClass{

    @Autowired Dao dao;

    @Transactional(propagation = Propagation.REQUIRED)
    public bigMethod(int someArgument){
      Data data1 = process(someArgument);
      Data data2 = process(someArgument+1);
      doSave(data1);
      doSave(data2);
    }
    
    private void doSave(Data data){
     this.dao.save(data);
    }

注意第二个代码在两者之间添加了一个私有方法。 而单独 class 中的 dao.save() 方法如下:

public class DAO{
 @Autowired Repository repo;
 @Transactional(propagation = Propagation.REQUIRED)   
  public void save(Data data){
  repo.save(data);
  }
 }

为了 Spring 为您提供事务传播等服务,它需要能够在调用之间拦截或“插入自身”。

当您调用 dao.bigMethod 时,dao 对象并不是真正的 Dao 实例 class,但实际上是 Spring Dao 的 AOP 代理 class ,它还有一个 bigMethod 函数。当您调用 AOP 代理上的 bigMethod 时 Spring 添加其服务,例如事务,然后调用您的 bigMethod class.

一旦进入 bigMethod 函数,您就处于常规 Java 函数中,Spring 看不到您进行的任何函数调用。因此,如果在 bigMethod 中调用另一个 Java 函数,如保存,Spring 将看不到它,并且无法添加任何更多的事务服务。

要从 Spring 获得更多服务,您必须将 save 移动到另一个 bean,并获取该 bean 的句柄,它将再次指向包含 save 的 class 的 AOP 代理.

一旦您拥有该 AOP 代理,当您调用它时 Spring 将再次为您提供事务服务,即使调用点在私有函数内也是如此。