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