同一个Class中方法调用Spring事务不起作用
2023-04-12
问题描述
开发中避免不了会对同一个类里面的方法调用,比如有一个类Test,它的一个方法A,A再调用本类的方法B(不论方法B是用public还是private修饰),但方法A没有声明注解事务,而B方法有。则外部调用方法A之后,方法B的事务是不会起作用的。这也是经常犯错误的一个地方。这是由于使用Spring AOP代理造成的,因为只有当事务方法被当前类以外的代码调用时,才会由Spring生成的代理对象来管理。
在AreaService 类中,如果insert和deleteById开启了事务,但是调用的方法insertDelete没有开启事务,那么这两个被调用的方法也开启不了事务。
@Service
public class AreaService {
@Autowired
private AreaMapper areaMapper;
//没有加事务
public void insertDelete(Area area){
this.insert(area);//虽然方法内部出现异常,但是上面的areaMapper.insert(area);还是会执行并插入到数据库
int abc = 1/0; //出现异常,程序结束
this.deleteById(area.getId());//不会执行
}
@Transactional(propagation =Propagation.REQUIRES_NEW)
public int insert(Area area) {
area.setDelFlag(0);
area.setCreateTime(LocalDateTime.now());
int insert = areaMapper.insert(area);
int a = 1/0;//虽然此处出现异常,但是上面的areaMapper.insert(area);还是会执行并插入到数据库
return insert;
}
@Transactional(propagation =Propagation.REQUIRES_NEW)
public int deleteById(Long id) {
Long[] ids = {
id};
return areaMapper.updateDelFlagByIds(ids);
}
}
解决方法
- 注入自身(比较快捷)
- 拆成两个类(略有点麻烦)
- AopContext.currentProxy()获取代理类(使用起来有点麻烦)
- 使用手写事务(容易出现事务未关闭的情况)
注入自身的示例:
@Service
public class AreaService {
@Autowired
private AreaMapper areaMapper;
@Autowired
private AreaService service;//将自身service注入
//没有加事务
public void insertDelete(Area area){
service.insert(area);
int abc = 1/0; //出现异常,程序结束
service.deleteById(area.getId());//不会执行
}
@Transactional(propagation =Propagation.REQUIRES_NEW)
public int insert(Area area) {
area.setDelFlag(0);
area.setCreateTime(LocalDateTime.now());
int insert = areaMapper.insert(area);
int a = 1/0;//出现异常,事务回滚
return insert;
}
@Transactional(propagation =Propagation.REQUIRES_NEW)
public int deleteById(Long id) {
Long[] ids = {
id};
return areaMapper.updateDelFlagByIds(ids);
}
}
本文仅代表作者观点,版权归原创者所有,如需转载请在文中注明来源及作者名字。
免责声明:本文系转载编辑文章,仅作分享之用。如分享内容、图片侵犯到您的版权或非授权发布,请及时与我们联系进行审核处理或删除,您可以发送材料至邮箱:service@tojoy.com



