目前有一個需求就是一個serviceA裏有一個doService()方法提供給外部調用, doSomeThing調用了類裏另外三個方法doA(), save1(), save2();它們的關係如下:
ServiceA{
doService(){
loop{
doA();
}
}
doA(){
save1();
save2();
}
save1(){
}
save2(){}
}
現在要實現的是在執行save2()方法出現異常時save1()保存的數據進行回滾,但不能回滾整個doService的事務,一般的做法是這樣的
ServiceA{
@Transactional(propagation = Propagation.REQUIRED)
doService(){
loop{
doA();
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
doA(){
save1();
save2();
}
save1(){
}
save2(){}
}
很容易理解把doA方法放在一個新的事務裏面這果出現異常時只會回滾新起的事務,不會回滾doService()的事務
這樣的是沒效果的,不是因爲配置有問題,是因爲事務管理原理是spring 通過動態代理來AOP攔截到調用方法來進行事務管理的
所以不能直接調用doA()方法,只能通過spring產生的代理類來訪問該方法纔可以.解決方法是在這個類本身注入一個它的一個代理類來調用如:
ServiceA{
@Autowired
private ServiceA serviceA;
@Transactional(propagation = Propagation.REQUIRED)
doService(){
loop{
serviceA.doA();
}
}
@Transactional(propagation = Propagation.REQUIRES_NEW)
doA(){
save1();
save2();
}
save1(){
}
save2(){}
}