spring事务管理,for循环删除数据时,如果有一条失败则回滚一条数据
场景:单个删除时,需要提示具体删除失败的原因;批量删除时,需要提示删除失败总数。单个删除A和批量删除B都调用同一个方法C,区别是单个删除时传入的业务id放到list中再调用删除方法,这样后续删除如果有改动只需要改删除方法C就行,不需要改动A和B。为了保持事务一致,需要在A和B方法上添加注解@Transactional。C方法上可以不添加。经过上述操作,可以在使用for循环删除数据时,如果有一条删除
·
场景:单个删除时,需要提示具体删除失败的原因;批量删除时,需要提示删除失败总数。单个删除A和批量删除B都调用同一个方法C,区别是单个删除时传入的业务id放到list中再调用删除方法,这样后续删除如果有改动只需要改删除方法C就行,不需要改动A和B。为了保持事务一致,需要在A和B方法上添加注解@Transactional。C方法上可以不添加。代码如下:
方法A:
@Transactional
@Override
public void remove(Long id) {
List<Long> businessIds = Collections.singletonList(id);
RemoveDto removeDto = getRemoveDto( businessIds);;
if(!CollectionUtils.isEmpty(removeDto.getErrorData())){
throw new Exception("删除失败");
}
}
方法B:
@Transactional
@Override
public RemoveDto removeBatch(List<Long> ids) {
return getRemoveDto(ids);
}
方法C:
private RemoveDto getRemoveDto(List<Long> ids) {
if (CollectionUtils.isEmpty(ids)){
throw new Exception( "请求参数不能为空");
}
int success = 0;
int fail = 0;
for (Long id: ids) {
Object savePoint = null;
try {
//设置回滚点
savePoint = TransactionAspectSupport.currentTransactionStatus().createSavepoint();
remove(id);//该方法只是删除数据和相关的业务逻辑,方法也不需要添加@Transactional,同时该方法和方法C可以不在同一个类中
success++;
}catch (Exception e){
fail++;
log.error("系统异常删除原因:"+ JSON.toJSONString(e));
if (savePoint != null) {
//回滚
TransactionAspectSupport.currentTransactionStatus().rollbackToSavepoint(savePoint);
}
}
}
return RemoveDto.builder().successCount(success).failCount(fail).build();
}
经过上述操作,可以在使用for循环删除数据时,如果有一条删除失败,会回滚失败的数据,并且不影响已经删除成功的数据和未删除的数据。
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐

所有评论(0)