2018-10-23
常用的四種方案:
1 嘉熊、基于數(shù)據(jù)庫表做樂觀鎖,用于分布式鎖
增加版本號
缺點:增加了一次select版本號操作、數(shù)據(jù)庫開銷大垄开、可能臟數(shù)據(jù)
2 、使用memcached的add方法税肪,用于分布式鎖
add使用時指定有效時間溉躲,發(fā)生宕機,也會釋放資源益兄,避免死鎖
3 锻梳、使用redis的setnx、expire方法
同上
4 净捅、使用redis的setnx疑枯、get、getset方法
針對上面3可能出現(xiàn)死鎖(在expire執(zhí)行前宕機)
1. setnx(lockkey, 當前時間+過期超時時間) 蛔六,如果返回1荆永,則獲取鎖成功;如果返回0則沒有獲取到鎖国章,轉(zhuǎn)向2具钥。
2. get(lockkey)獲取值oldExpireTime ,并將這個value值與當前的系統(tǒng)時間進行比較液兽,如果小于當前系統(tǒng)時間骂删,則認為這個鎖已經(jīng)超時,可以允許別的請求重新獲取四啰,轉(zhuǎn)向3宁玫。
3. 計算newExpireTime=當前時間+過期超時時間,然后getset(lockkey, newExpireTime) 會返回當前l(fā)ockkey的值currentExpireTime拟逮。
4. 判斷currentExpireTime與oldExpireTime 是否相等撬统,如果相等,說明當前getset設置成功敦迄,獲取到了鎖恋追。如果不相等,說明這個鎖又被別的請求獲取走了罚屋,那么當前請求可以直接返回失敗苦囱,或者繼續(xù)重試。
5. 在獲取到鎖之后脾猛,當前線程可以開始自己的業(yè)務處理撕彤,當處理完畢后,比較自己的處理時間和對于鎖設置的超時時間,如果小于鎖設置的超時時間羹铅,則直接執(zhí)行delete釋放鎖蚀狰;如果大于鎖設置的超時時間,則不需要再鎖進行處理职员。
不常用的方案:
1 使用memcached的cas方法
2 使用redis的watch麻蹋、multi、exec命令
3 使用zookeeper