最新国产好看的视频,伊人天堂AV在线,国产Aaaaaa视频,蜜臀视频在线观看一区,人妻av色图,密臀久久久精品影片,青青视频免费观看毛片,久草在线观看视,国产三级精品色情在线

Redis分布式鎖一定要避開的兩個坑

 更新時間:2023年04月13日 09:03:40   作者:JAVA前線  
這篇文章主要為大家詳細介紹了Redis中分布式鎖一定要避開的兩個坑以及對應(yīng)的解決方法,文中的示例代碼講解詳細,希望對大家有所幫助

1 第一個坑:錯誤釋放鎖時機

1.1. 發(fā)現(xiàn)問題

分析以下代碼存在什么問題:

// 分布式鎖服務(wù)
public interface RedisLockService {
    // 獲取鎖
    public boolean getLock(String key);
    // 釋放鎖
    public boolean releaseLock(String key);
}

// 業(yè)務(wù)服務(wù)
public class BizService {

    @Resource
    private RedisLockService redisLockService;

    public void bizMethod(String bizId) {
        try {
            // 獲取鎖
            if(redisLockService.getLock(bizId)) {
                // 業(yè)務(wù)重復校驗
                if(!bizValidate(bizId)) {
                    throw new BizException(ErrorBizCode.REPEATED);
                }
                // 執(zhí)行業(yè)務(wù)
                return doBusiness();
            }
            // 獲取鎖失敗
            throw new BizException(ErrorBizCode.GET_LOCK_ERROR);
        } finally {
            // 釋放鎖
            redisLockService.releaseLock(bizId);
        }
    }
}

上述代碼看似沒問題,實則隱藏大問題。問題在于釋放鎖時沒有校驗當前線程是否拿到鎖:

  • 線程1和線程2同一時刻訪問業(yè)務(wù)方法
  • 線程2獲取鎖成功,進行業(yè)務(wù)處理
  • 線程1沒有獲取到鎖,但是釋放鎖成功
  • 此時有線程3嘗試獲取鎖成功,但是線程2業(yè)務(wù)沒有處理完,所以線程3不會導致業(yè)務(wù)重復異常
  • 最終導致線程2和線程3重復執(zhí)行業(yè)務(wù)

1.2 解決問題

解決方案是在確認獲取鎖成功后才允許釋放鎖:

public class BizService {

    @Resource
    private RedisLockService redisLockService;

    public void bizMethod(String bizId) {
        boolean getLockSuccess = false;
        try {
            // 嘗試獲取鎖
            getLockSuccess = redisLockService.getLock(bizId);
            // 獲取鎖成功
            if(getLockSuccess) {
                // 業(yè)務(wù)重復校驗
                if(!bizValidate(bizId)) {
                    throw new BizException(ErrorBizCode.REPEATED);
                }
                // 執(zhí)行業(yè)務(wù)
                return doBusiness();
            }
            // 獲取鎖失敗
            throw new BizException(ErrorBizCode.GET_LOCK_ERROR);
        } finally {
            // 獲取鎖成功才允許釋放鎖
            if(getLockSuccess) {
                redisLockService.releaseLock(bizId);
            }
        }
    }
}

2 第二個坑:緩存失效問題

第二個問題是Redis還存在內(nèi)存清理機制,可能會導致分布式鎖失效。

2.1 過期清理機制

(1) 定期刪除

Redis定時檢查哪些key已經(jīng)過期,發(fā)現(xiàn)過期則刪除

(2) 惰性刪除

如果key非常多,定期刪除會非常消耗資源,所以引入惰性刪除策略

如果Redis訪問key時發(fā)現(xiàn)已經(jīng)過期則直接刪除

2.2 內(nèi)存回收機制

當內(nèi)存不足時Redis會選擇一些元素進行刪除:

no-enviction

禁止驅(qū)逐數(shù)據(jù),新寫入操作會報錯

volatile-lru

從已設(shè)置過期時間的數(shù)據(jù)集選擇最近最少使用的數(shù)據(jù)淘汰

volatile-ttl

從已設(shè)置過期時間的數(shù)據(jù)集選擇將要過期的數(shù)據(jù)淘汰

volatile-random

從已設(shè)置過期時間的數(shù)據(jù)集選擇任意的數(shù)據(jù)淘汰

allkeys-lru

從數(shù)據(jù)集選擇最近最少使用的數(shù)據(jù)淘汰

allkeys-random

從數(shù)據(jù)集選擇任意的數(shù)據(jù)淘汰

至少存在兩種場景導致分布式鎖失效問題:

  • 場景一:Redis內(nèi)存不足進行內(nèi)存回收,使用allkeys-lru或者allkeys-random回收策略導致鎖失效
  • 場景二:線程獲取分布式鎖成功,但處理業(yè)務(wù)時間過長,此時鎖到期被定時清理,導致其它線程獲取鎖成功并重復執(zhí)行業(yè)務(wù)

2.3 樂觀鎖

通用方案是在數(shù)據(jù)庫層保護,例如庫存扣減業(yè)務(wù)在數(shù)據(jù)庫層用樂觀鎖,原理參看《MySQL樂觀鎖扣減庫存原理圖解》這篇文章。

udpate goods set stock = stock - #{acquire} 
where sku_id = #{skuId} and stock - #{acquire} >= 0

到此這篇關(guān)于Redis分布式鎖一定要避開的兩個坑的文章就介紹到這了,更多相關(guān)Redis分布式鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • 深入解析Redis的LRU與LFU算法實現(xiàn)

    深入解析Redis的LRU與LFU算法實現(xiàn)

    這篇文章主要重點介紹了Redis的LRU與LFU算法實現(xiàn),并分析總結(jié)了兩種算法的實現(xiàn)效果以及存在的問題,并闡述其優(yōu)劣特性,感興趣的小伙伴跟著小編一起來看看吧
    2023-07-07
  • Redis集群水平擴展、集群中添加以及刪除節(jié)點的操作

    Redis集群水平擴展、集群中添加以及刪除節(jié)點的操作

    這篇文章主要介紹了Redis集群水平擴展、集群中添加以及刪除節(jié)點的操作,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2021-03-03
  • redis做websocket分布式消息推送服務(wù)的實現(xiàn)

    redis做websocket分布式消息推送服務(wù)的實現(xiàn)

    本文介紹了使用Redis作為消息隊列實現(xiàn)WebSocket分布式消息推送服務(wù)的方案,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2024-12-12
  • Redis 2.8-4.0過期鍵優(yōu)化過程全紀錄

    Redis 2.8-4.0過期鍵優(yōu)化過程全紀錄

    這篇文章主要給大家介紹了關(guān)于Redis 2.8-4.0過期鍵優(yōu)化的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學習或者使用Redis具有一定的參考學習價值,需要的朋友們下面來一起學習學習吧
    2019-04-04
  • Redis實現(xiàn)主從復制方式(Master&Slave)

    Redis實現(xiàn)主從復制方式(Master&Slave)

    這篇文章主要介紹了Redis實現(xiàn)主從復制方式(Master&Slave),具有很好的參考價值,希望對大家有所幫助。如有錯誤或未考慮完全的地方,望不吝賜教
    2022-06-06
  • 解決Redis分布式鎖的誤刪問題和原子性問題

    解決Redis分布式鎖的誤刪問題和原子性問題

    Redis的分布式鎖是通過利用Redis的原子操作和特性來實現(xiàn)的,為了保證數(shù)據(jù)的一致性和避免沖突,可以使用分布式鎖來進行同步控制,本文給大家介紹了如何解決Redis分布式鎖的誤刪問題和原子性問題,需要的朋友可以參考下
    2024-02-02
  • Redis總結(jié)筆記(一):安裝和常用命令

    Redis總結(jié)筆記(一):安裝和常用命令

    這篇文章主要介紹了Redis總結(jié)筆記(一):安裝和常用命令,本文著重總結(jié)了常用命令,如對value操作的命令、對String操作的命令、對List操作的命令、對Set操作的命令等,需要的朋友可以參考下
    2015-01-01
  • Redis使用ZSET實現(xiàn)消息隊列的項目實踐

    Redis使用ZSET實現(xiàn)消息隊列的項目實踐

    本文主要介紹了Redis使用ZSET實現(xiàn)消息隊列的項目實踐,文中通過示例代碼介紹的非常詳細,對大家的學習或者工作具有一定的參考學習價值,需要的朋友們下面隨著小編來一起學習學習吧
    2023-07-07
  • Redis的數(shù)據(jù)存儲及String類型的實現(xiàn)

    Redis的數(shù)據(jù)存儲及String類型的實現(xiàn)

    這篇文章主要介紹了Redis的數(shù)據(jù)存儲及String類型的實現(xiàn),redis作為k-v數(shù)據(jù)存儲,因查找和操作的時間復雜度都是O(1)和豐富的數(shù)據(jù)類型及數(shù)據(jù)結(jié)構(gòu)的優(yōu)化,了解了這些數(shù)據(jù)類型和結(jié)構(gòu)更有利于我們平時對于redis的使用,需要的朋友可以參考下
    2022-10-10
  • Redis實現(xiàn)分布式隊列淺析

    Redis實現(xiàn)分布式隊列淺析

    Redis將數(shù)據(jù)存儲在內(nèi)存中,使得讀寫速度非???,經(jīng)常被用來做緩存系統(tǒng),這里我們將redis用來做一個分布式的消息隊列。這篇文章主要介紹了使用redis來作為消息隊列,并且進行分布式主從配置,有需要的朋友可以參考借鑒,下面來一起看看吧。
    2016-11-11

最新評論

从江县| 凤城市| 兴山县| 美姑县| 阜宁县| 黄浦区| 宜城市| 景德镇市| 阳江市| 木兰县| 图木舒克市| 仙桃市| 万载县| 榆林市| 漾濞| 三门县| 怀仁县| 宜昌市| 金秀| 祁东县| 云南省| 十堰市| 扎囊县| 双峰县| 封开县| 忻城县| 陇西县| 长汀县| 合山市| 屏东市| 延寿县| 内乡县| 龙陵县| 开原市| 图片| 巴中市| 岳阳县| 藁城市| 阿城市| 万州区| 九江县|