目錄
項目場景:
問題描述
原因分析:
解決方案:
其他解決方案:
項目場景:
oracle 數(shù)據(jù)庫在做大量的批量更新同一張表數(shù)據(jù)。
問題描述
早上來公司去生產(chǎn)環(huán)境查grelog日志,發(fā)現(xiàn)ERROR日志,點進去看后報如下錯誤:
ORA-00060: deadlock detected while waiting for resource
原因分析:
從錯誤的中一看就知道oracle 數(shù)據(jù)庫發(fā)生了死鎖。去生產(chǎn)的log日志查看,發(fā)現(xiàn)同一時間點左右,還有一個批量更新同一條數(shù)據(jù)的慢sql 日志。這個慢sql 的更新和這個死鎖的sql 更新互斥了。導(dǎo)致了死鎖。 死鎖的異常拋出后,這個慢sql 就執(zhí)行成功了。
在本地也寫單元測試實例,跑出了同樣的結(jié)果。猜測是因為更新主鍵SequenceNo更新時亂序?qū)е碌乃梨i。
解決方案:
在執(zhí)行批量更新前,先對主鍵序列號進行排序,然后在進行批量更新。
例如:A線程更新的主鍵是1,2,3? B線程更新的主鍵是3,2,1 當(dāng)批量更新時就可能會死鎖,但是排序后,A線程更新的主鍵是1,2,3?B線程更新的主鍵是1,2,3 這是就不會產(chǎn)生死鎖,測試過。這種情況多線程,跑了兩天也沒發(fā)生過死鎖。
代碼如下:
objects.stream().sorted((a1, a2) -> a1.getSequenceNo().compareTo(a2.getSequenceNo()));
int[] execute = dsl.batchUpdate(objects.stream().map(i -> {
ARecord r = new ARecord();
r.setSequenceNo(i.getSequenceNo());
r.setTime(i.getTime());
r.setResult(i.getResult());
r.changed(table.SEQUENCE_NO, false);
return r;
}).collect(Collectors.toList())).execute();
return Integer.parseInt(String.valueOf(Arrays.stream(execute).count()));
其他解決方案:
當(dāng)時討論的還有其他解決方案,如下:
1 可以更新前加鎖,避免導(dǎo)致死鎖
2 可以把批量更新成單條更新操作文章來源:http://www.zghlxwxcb.cn/news/detail-585148.html
但是通過分析發(fā)票,這些方案都是會影響程序的性能,導(dǎo)致性能變慢,還有對代碼的修改比較大,有很大的不確定性和風(fēng)險。綜上綜合考慮選擇批量更新前排序解決次問題。文章來源地址http://www.zghlxwxcb.cn/news/detail-585148.html
到了這里,關(guān)于解決oracle死鎖,生產(chǎn)問題,ORA-00060: deadlock detected while waiting for resource,的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!