一、背景
由于某业务需要回退某产品数据缓存列表Asset资源,主任务执行后,通过并行执行批量子任务进行数据回退,子任务中会记录缓存列表Asset和缓存列表行AssetLine数据,并行执行过程会出现缓存列表行AssetLine重复插入问题,导致后续业务执行变更资源时候报错。
以前写过一篇也是利用无事务方式解决并发问题,主要是通过获取插入后的自增主键id,防止并发场景,再次查询一次,如果id一致,则代表插入成功,如果id不一致,则代表插入失败,删除这条旧数据。利用无事务方式插入数据库解决并发插入问题,本文通过另一种思路无事务解决并发插入数据库,数据重复问题。
二、方案实现
1.先根据id查询数据库中是否存在该数据,如果存在则代表已经插入过了,直接返回
2.如果不存在此条数据,插入数据库
3.获取插入后的自增主键id,查询SQL倒序desc排序
4.防止并发场景,再次查询一次,
查询出来的数据是按照id倒序,最后1条id最小。
如果id最小的不是当前插入的id,表示当前入库之前已经有数据入库,需要失效当前数据,
然后取id最小的那1条作为有效数据。
伪代码实现
// 当前需要插入的数据
AssetLine needAddAssetLine;
// 根据assetId查询当前数据
Lisst<AssetLine> assetLineList = findByAssetId(assetId);
Optional<AssetLine> minIdVo = assetLineList.stream().min(Comparator.comparing(AssetLine::getId));
if(minIdVo.isPresent()){AssetLine minIdAssetLine = minIdVo.get();if(needAddAssetLine.getId() != minIdAssetLine.getId()){//失效需要新增的数据 int count = updateByAssetId(needAddAssetLine.getId());if(count != 0){needAddAssetLine.setId(minIdAssetLine.getId());}}
}