背景
多人併發操作同一數據,可能導致數據不一致,數據不一致可是非常可怕的bug。
業務場景
工作流業務,如員工A操作工單審批通過,同時員工B也操作了相同的工單審批拒絕,
此時這個工單狀態字段可能出現不一致情況。
問題來了
這時運營妹子就會來找你,這條數據我不是審批通過了嗎,怎麼又拒絕了
程序汪,看了半天生產日誌【某工單數據被多人同時操作了】,分析後發現是數據併發操作沒加鎖導致的。
解決思路
- 【synchronized 解決思路】程序汪,想想java 不是有個叫synchronized ,可以鎖方法。然後程序汪很開心的改好代碼,提交git 上生產了。第二天,運營妹子又來找程序汪,生產還是出現這個問題。程序汪很痛苦,為啥還沒防止住啊。後來又查了查資料,發現分佈式環境下synchronized鎖不住。後面在專門開篇講synchronized的應用場景
- 【select X for udpate 解決思路】程序汪想了一夜,終於發現可以利用mysql中的行鎖嘛 for update,說幹就幹,程序汪馬上把操作工單表的sql 後面加了 for update.自己用多線程 mock了一把,發現真防止住了。這下程序汪可以放心的睡覺了。
- 【悲觀鎖含義】上來就先鎖住,然後執行相應的業務邏輯,這就叫悲觀鎖。
事務{
lock 工單表, select * from 工單表 where id=XX for update
其他表,日誌表等等
}
注意
- sql的where 條件是鎖某行,粗心的程序汪可別鎖成表啦,那運營妹子可會天天來找你麻煩。
- 別亂用,考慮業務是否有分佈式併發場景。
- for update時,需要放在事務中
防併發請找方便的for update,鎖還有好多種,各有優缺點。
如果覺得對你有幫助請關注,有錯誤請指點,下篇繼續分析【樂觀鎖的典案例應用舉例】
閱讀更多 程序汪汪 的文章