如下例:
public class MyServiceImpl implements MyService {
public void do(){
//the transaction annotation won't work if you directly invoke handle() method with 'this'
this.handle();
}
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void handle() {
//sth with transaction
}
}
如果直接调用this的handle()方法则事务无法生效,原因是spring的AOP是通过代理实现的,像这样直接调用本对象的方法是不会应用代理的。
可以使用如下两种方式修改代码以应用事务:
(1)在MyServiceImpl中声明一个MyService对象
public class MyServiceImpl implements MyService {
@Autowired
private MyService myService;
public void do(){
//use myService object
myService.handle();
}
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void handle() {
//sth. with transaction
}
}
(2)使用AopContext类
public class MyServiceImpl implements MyService {
public void do(){
//fetch current proxy objet from AopContext
((MyService)AopContext.currentProxy()).handle();
}
@Transactional(propagation=Propagation.REQUIRED, rollbackFor=Exception.class)
public void handle() {
//sth with transaction
}
}
注意,原生的AspectJ是不会有这种自身调用的问题的,因为它不是基于代理的AOP框架。
欢迎关注我的公众号“彤哥读源码”,查看更多“源码&架构&算法”系列文章, 与彤哥一起畅游源码的海洋。