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



根据我的理解,私有方法不能在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);
}

注意,第二段代码在中间添加了一个私有方法。而dao.save()方法位于一个单独的类中,如下所示:

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

为了让Spring为您提供诸如事务传播之类的服务,它需要能够拦截或"插入自己"。

当你叫道。bigMethod dao对象实际上并不是dao类的实例,而实际上是dao类的Spring AOP代理,它也有一个bigMethod函数。当你在AOP代理上调用bigMethod时,Spring会添加它的服务,比如事务,然后调用你的bigMethod类。

一旦你在bigMethod函数中,你就只是在一个普通的Java函数中,Spring看不到你所做的任何函数调用。因此,如果在bigMethod中调用另一个Java函数,例如save, Spring将不会看到它,并且无法添加任何事务服务。

要从Spring获得进一步的服务,必须将save移动到另一个bean,并获得该bean的句柄,该句柄将再次指向包含save的类的AOP代理。

一旦你有了AOP代理,当你调用它时,Spring将再次为你提供事务服务,即使调用的点是在私有函数中。

最新更新