前言:由于一些原因簡書已經(jīng)一年多沒有更新,最近開始會重新維護起來汁果,后續(xù)會分享一些自己沉淀的東西泌神!
一、樂觀鎖
常用實現(xiàn)樂觀鎖方式:
1毅弧、表里面添加version字段(默認1),在更新的時候同時添加version校驗当窗,如:
update XXX set XXX,version=version + 1 where version = 原version(入?yún)魅?
這個用法會用在前端配置防止并發(fā)以及重置够坐,切記在更新的時候該version需要從前端帶到后端,這種方式有些局限性,version字段沒有實際的語義
2崖面、表里面添加狀態(tài)字段元咙,來作為前置狀態(tài)校驗,比如訂單表中支付成功需要將已創(chuàng)建待支付的訂單更新為已支付
update XXX set status = 'PAID' where status = 'UNPAID'
這個用法使用很廣如在訂單中心或者一些中臺業(yè)務系統(tǒng)
不常用的實現(xiàn)樂觀鎖方式:
3巫员、實現(xiàn)方式跟第一點類似庶香,因為我們表里面經(jīng)常會有更新時間gmt_modified字段,該字段可以設置為TIMESTAMP(3)(精確到1ms)
這種的像更新訂單表里面的某幾個字段可能不好用第二種情況狀態(tài)機來控制简识,用時間戳來作為樂觀鎖也是一種很好的方式
update XXX set attribute = XXX where gmt_modified = XXX
二赶掖、悲觀鎖
悲觀鎖不要輕易使用,能不用的就不要使用七扰,因為悲觀鎖是獨占鎖奢赂,其余任務更新被鎖住的數(shù)據(jù)會等待。使用方式:
select * from XXX where id=1 for update
有個點必須注意颈走,因為默認情況下數(shù)據(jù)庫更新操作都是自動提交的膳灶,所以在應用層使用悲觀鎖的時候應該放在事物中
有個典型的需要使用悲觀鎖的場景,比如一個主訂單下面有2個子訂單,當子訂單都被取消的時候需要將主訂單的狀態(tài)推成取消轧钓。兩個子訂單同時在兩個不同的請求調(diào)用中被取消序厉,這個時候需要使用悲觀鎖鎖住先鎖主主訂單防止并發(fā),最終當兩個子單都被取消的時候主訂單狀態(tài)被推成取消
三毕箍、數(shù)據(jù)庫鎖應用暢想
數(shù)據(jù)庫鎖是一種相對比較簡單的防止并發(fā)的有效方案弛房,在一些通過定時任務來調(diào)度的任務,當需要同時執(zhí)行 n個定時任務的時候霉晕,為了處理并發(fā)這個時候采用樂觀鎖中第2條通過明確的狀態(tài)機搶占到數(shù)據(jù)再去處理庭再,這樣就能做到同一個單據(jù)被重復撈取。如上就是一些比較基本的手段牺堰,掌握好就可以通過不同的場景交叉使用拄轻。