分布式鎖
更新時間 2024-11-06 15:48:44
最近更新時間: 2024-11-06 15:48:44
分享文章
業務場景分析
多個并發請求同時修改同一份數據, 比如多個營業員并發對同一個客戶的資料進行修改。 同時修改同一份數據會并發沖突,導致數據不正確的可能,對業務產生不可預估的影響。目前幾乎很多大型網站及應用都是分布式部署的,分布式場景中的數據一致性問題一直是一個比較重要的話題。
解決方案
對于分布式鎖可以基于數據庫實現分布式鎖 ,但帶來的問題是性能不足,無法滿足大型應用的高并發使用場景。這時基于緩存(Redis等)去實現分布式鎖,帶來了顯著性能優勢。
Redis實現分布式鎖的原理是基于: 存在判斷KEY是否存在的命令,以及KEY設置TTL,防止死鎖的機制。
下面是一個簡單的實現思路:
(1)獲取鎖的時候,使用setnx加鎖,并使用expire命令為鎖添加一個超時時間,超過該時間則自動釋放鎖,鎖的value值為一個隨機生成的UUID,通過此在釋放鎖的時候進行判斷。
(2)獲取鎖的時候還設置一個獲取的超時時間,若超過這個時間則放棄獲取鎖。
(3)釋放鎖的時候,通過UUID判斷是不是該鎖,若是該鎖,則執行delete進行鎖釋放。
由于開源已經有非常多成熟的方案, 下面是基于redisson(一個開源的JAVA redis庫)實現分布式鎖,可參考如下示例:
maven
<dependency>
<groupId>org.redisson</groupId>
<artifactId>redisson</artifactId>
<version>3.25.0</version>
</dependency>
示例代碼
RLock?lock?=?redisson.getLock("myLock");
//?traditional?lock?method
lock.lock();
//?or?acquire?lock?and?automatically?unlock?it?after?10?seconds
lock.lock(10,?TimeUnit.SECONDS);
//?or?wait?for?lock?aquisition?up?to?100?seconds?
//?and?automatically?unlock?it?after?10?seconds
boolean?res?=?lock.tryLock(100,?10,?TimeUnit.SECONDS);
if?(res)?{
???try?{
?????...
???}?finally?{
???????lock.unlock();
???}
}