一、背景
由于某業務需要回退某產品數據緩存列表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());}}
}