引言
多個進程或線程同時(或著說在同一段時間內(nèi))訪問同一資源會產(chǎn)生并發(fā)問題。
?
銀行兩操作員同時操作同一賬戶就是典型的例子。比如A、B操作員同時讀取一余額為1000元的賬戶,A操作員為該賬戶增加100元,B操作員同時為該賬戶減去 50元,A先提交,B后提交。 最后實際賬戶余額為1000-50=950元,但本該為1000+100-50=1050。這就是典型的并發(fā)問題。
?
從事零售供應(yīng)鏈庫存業(yè)務(wù),對庫存數(shù)量操作增減十分頻繁,同樣存在類似上述銀行取款遇到的問題,庫存數(shù)量操作有誤勢必給前臺銷售產(chǎn)生損失影響,因此需要關(guān)注對庫存數(shù)量并發(fā)操作下的一致性。
?
下面通過一個真實的案例分享在并發(fā)情況下如何保證庫存數(shù)量的準(zhǔn)確性。
問題是什么-加鎖失效
看看下面這段流程和代碼,思考會有并發(fā)問題嗎?
?
1.加鎖前,獲取箱子明細數(shù)據(jù),此處在鎖之外,存在并發(fā)臟讀問題
?
2.加鎖后,并進行箱子上架分批次回傳業(yè)務(wù)處理
?
3.加鎖后,更新箱子明細上架數(shù)量邏輯:已上架數(shù)量 = 加鎖前的明細數(shù)據(jù)(臟讀) + 報文回傳的明細數(shù)據(jù) 直接進行行更新
原因是什么-加鎖的位置不正確
核心的問題原因
1.業(yè)務(wù)分布式鎖失效:使用分布式鎖加鎖了,但是仍然使用加鎖前查詢的數(shù)據(jù),導(dǎo)致出現(xiàn)臟讀
2.Mysql鎖失效:數(shù)據(jù)庫更新時,未上任何鎖,導(dǎo)致臟讀的數(shù)據(jù)直接覆蓋更新當(dāng)前行
?
有同學(xué)這時問了,為啥防重碼也沒有生效呢?
防重碼主要是用作冪等邏輯的,同一個請求多次處理,結(jié)果仍然是相同的。
但是這是兩次不同的請求,防重碼是不同的,因此不能只依賴防重碼保證一致性。
?
解決方案有哪些
1、代碼層面:使用鎖(如互斥鎖、讀寫鎖、分布式鎖等)來控制資源的訪問,數(shù)據(jù)獲取的全部操作都需要再獲取鎖后才進行。
將獲取箱子明細的代碼移動到加鎖之后,只有獲取到分布式鎖,才能執(zhí)行分批次上架查詢和更新(串行化)
對應(yīng)改造后的代碼:
?
2、數(shù)據(jù)庫層面:實現(xiàn)事務(wù)管理,確保數(shù)據(jù)的一致性;合理設(shè)置事務(wù)隔離級別,以防止臟讀、或者采用樂觀鎖或悲觀鎖來處理并發(fā)更新,合理設(shè)計查詢效率,減少鎖競爭。
數(shù)據(jù)庫的并發(fā)上鎖處理和業(yè)務(wù)代碼的上鎖是互補的關(guān)系
因為無法保證后續(xù)業(yè)務(wù)的調(diào)整或其他業(yè)務(wù)代碼的調(diào)用能始終保持獲取數(shù)據(jù)的一致性,數(shù)據(jù)庫的并發(fā)上鎖處理更多是一種兜底保證機制。
?
樂觀鎖更新
?
悲觀鎖更新
?
擴展方案
1.應(yīng)用程序設(shè)計: 在應(yīng)用程序設(shè)計階段,盡量避免長時間持有數(shù)據(jù)庫連接或事務(wù),減少并發(fā)操作的可能性,利用AI代碼評審或者人工提前找出可能出現(xiàn)并發(fā)問題的地方;合理設(shè)置鎖的粒度,避免鎖失效。
?
1. 網(wǎng)絡(luò)負(fù)載層面:采用限流控制訪問頻率;采用分布式數(shù)據(jù)庫,進行數(shù)據(jù)分片,降低單節(jié)點并發(fā)壓力;使用負(fù)載均衡,將網(wǎng)絡(luò)請求分發(fā)到不同的服務(wù)器,提高系統(tǒng)處理并發(fā)的能力,防止系統(tǒng)過載。
?
1.請求層面:前端點擊防重、系統(tǒng)冪等防重、盡可能降低同一請求的多次重試訪問引起的一致性問題。
?
通過以上措施,可以在不同層面有效地防止并發(fā)問題,保證系統(tǒng)的數(shù)據(jù)的一致性
審核編輯 黃宇
-
分布式
+關(guān)注
關(guān)注
1文章
997瀏覽量
75395 -
代碼
+關(guān)注
關(guān)注
30文章
4900瀏覽量
70713
發(fā)布評論請先 登錄
非阻塞賦值容易錯語法點討論
Linux高級編程---互斥鎖
STM32F427的FMC地址數(shù)據(jù)總線復(fù)用控制SRAM必須要加鎖存器嗎
設(shè)計電子密碼鎖時,怎么實現(xiàn)控制密碼輸錯幾次就不能再輸入的功能
帶自鎖功能的密碼鎖制作方法分享
Altium Designer規(guī)則設(shè)計技巧之過孔和焊盤

詳解非鎖/互鎖/自鎖的區(qū)別
指紋密碼鎖失效原因及對應(yīng)的解決方案
編程中常見的幾種鎖

select......for update會鎖表還是鎖行?
Linux互斥鎖的作用 互斥鎖是什么
數(shù)據(jù)庫如何實現(xiàn)分布式鎖
什么是分布式鎖 Redis的五種分布式鎖方案

評論