在开发中往往会遇到事务问题,当我们必须保证事务的时候,可以在进行具体的保存方法上面加上Spring的事务注解*@Transactional*,即如下的方式:
public class SomeServiceImpl implement ISomeService {
@Override
@Transactional
public void save() {
do saving...
}
}
或者这样的方式:
public class SomeServiceImpl implement ISomeService {
@Override
@Transactional
public void save() {
deal something...
doSave();
}
private void doSave() {
do saving...
}
}
这两种方式,注解@Transactional处于save()方法之上,这样是可以保证注解生效的,但是有时候会出现这样的一种情况:@Transactional不能放在save()方法之上,因为可能save()里面需要进行远程调用,结果逻辑变成了下面的方式:
public class SomeServiceImpl implement ISomeService {
@Override
public void save() {
deal something...
doSave();
remote procedure call...
}
@Override
@Transactional
private void doSave() {
do saving...
}
}
这种方式看起来没什么问题,但是由于SpringBoot是通过代理来进行扩展功能的(@Transactional的意思是生成SomeServiceImpl的代理类时,会为doSave方法加上事务),这样的话,由于save()没有声明事务,当doSave()出错时,里面的数据库操作是不会回滚的,这个就是SpringBoot自调用的事务问题,这个时候应该采用如下的方式:
public class SomeServiceImpl implement ISomeService {
@Autowired
ISomeService someService;
@Override
public void save() {
deal something...
someService.doSave();
remote procedure call...
}
@Override
@Transactional
public void doSave() {
do saving...
}
}
(或者也可以实现ApplicationContextAware,通过getBean来获取someService)
以上,亲测是可以进行事务回滚的,开发过程中踩到的坑啊,说明对Spring、SpringBoot的了解还不够深入,需要继续学习啊。