亚洲国产日韩欧美一区二区三区,精品亚洲国产成人av在线,国产99视频精品免视看7,99国产精品久久久久久久成人热,欧美日韩亚洲国产综合乱

搜索

Redis分布式鎖一定要避開(kāi)的兩個(gè)坑是什么

WBOY
發(fā)布: 2023-05-29 22:52:04
轉(zhuǎn)載
1321人瀏覽過(guò)

1 第一個(gè)坑:錯(cuò)誤釋放鎖時(shí)機(jī)

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

分析以下代碼存在什么問(wè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ù)重復(fù)校驗(yàn)
                if(!bizValidate(bizId)) {
                    throw new BizException(ErrorBizCode.REPEATED);
                }
                // 執(zhí)行業(yè)務(wù)
                return doBusiness();
            }
            // 獲取鎖失敗
            throw new BizException(ErrorBizCode.GET_LOCK_ERROR);
        } finally {
            // 釋放鎖
            redisLockService.releaseLock(bizId);
        }
    }
}
登錄后復(fù)制

上述代碼看似沒(méi)問(wèn)題,實(shí)則隱藏大問(wèn)題。問(wèn)題在于釋放鎖時(shí)沒(méi)有校驗(yàn)當(dāng)前線程是否拿到鎖:

  • 線程1和線程2同一時(shí)刻訪問(wèn)業(yè)務(wù)方法

  • 線程2獲取鎖成功,進(jìn)行業(yè)務(wù)處理

  • 線程1沒(méi)有獲取到鎖,但是釋放鎖成功

  • 此時(shí)有線程3嘗試獲取鎖成功,但是線程2業(yè)務(wù)沒(méi)有處理完,所以線程3不會(huì)導(dǎo)致業(yè)務(wù)重復(fù)異常

  • 最終導(dǎo)致線程2和線程3重復(fù)執(zhí)行業(yè)務(wù)

1.2 解決問(wèn)題

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

public class BizService {

    @Resource
    private RedisLockService redisLockService;

    public void bizMethod(String bizId) {
        boolean getLockSuccess = false;
        try {
            // 嘗試獲取鎖
            getLockSuccess = redisLockService.getLock(bizId);
            // 獲取鎖成功
            if(getLockSuccess) {
                // 業(yè)務(wù)重復(fù)校驗(yàn)
                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);
            }
        }
    }
}
登錄后復(fù)制

2 第二個(gè)坑:緩存失效問(wèn)題

第二個(gè)問(wèn)題是Redis還存在內(nèi)存清理機(jī)制,可能會(huì)導(dǎo)致分布式鎖失效。

2.1 過(guò)期清理機(jī)制

(1) 定期刪除

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

(2) 惰性刪除

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

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

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

當(dāng)內(nèi)存不足時(shí)Redis會(huì)選擇一些元素進(jìn)行刪除:

no-enviction

禁止驅(qū)逐數(shù)據(jù),新寫入操作會(huì)報(bào)錯(cuò)

文心一言
文心一言

文心一言是百度開(kāi)發(fā)的AI聊天機(jī)器人,通過(guò)對(duì)話可以生成各種形式的內(nèi)容。

文心一言1008
查看詳情 文心一言

volatile-lru

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

volatile-ttl

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

volatile-random

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

allkeys-lru

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

allkeys-random

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

至少存在兩種場(chǎng)景導(dǎo)致分布式鎖失效問(wèn)題:

  • 場(chǎng)景一:Redis內(nèi)存不足進(jìn)行內(nèi)存回收,使用allkeys-lru或者allkeys-random回收策略導(dǎo)致鎖失效

  • 場(chǎng)景二:線程獲取分布式鎖成功,但處理業(yè)務(wù)時(shí)間過(guò)長(zhǎng),此時(shí)鎖到期被定時(shí)清理,導(dǎo)致其它線程獲取鎖成功并重復(fù)執(zhí)行業(yè)務(wù)

2.3 樂(lè)觀鎖

通用方案是在數(shù)據(jù)庫(kù)層保護(hù),例如庫(kù)存扣減業(yè)務(wù)在數(shù)據(jù)庫(kù)層用樂(lè)觀鎖。

udpate goods set stock = stock - #{acquire} 
where sku_id = #{skuId} and stock - #{acquire} >= 0
登錄后復(fù)制

以上就是Redis分布式鎖一定要避開(kāi)的兩個(gè)坑是什么的詳細(xì)內(nèi)容,更多請(qǐng)關(guān)注php中文網(wǎng)其它相關(guān)文章!

相關(guān)標(biāo)簽:
最佳 Windows 性能的頂級(jí)免費(fèi)優(yōu)化軟件
最佳 Windows 性能的頂級(jí)免費(fèi)優(yōu)化軟件

每個(gè)人都需要一臺(tái)速度更快、更穩(wěn)定的 PC。隨著時(shí)間的推移,垃圾文件、舊注冊(cè)表數(shù)據(jù)和不必要的后臺(tái)進(jìn)程會(huì)占用資源并降低性能。幸運(yùn)的是,許多工具可以讓 Windows 保持平穩(wěn)運(yùn)行。

下載
來(lái)源:億速云網(wǎng)
本文內(nèi)容由網(wǎng)友自發(fā)貢獻(xiàn),版權(quán)歸原作者所有,本站不承擔(dān)相應(yīng)法律責(zé)任。如您發(fā)現(xiàn)有涉嫌抄襲侵權(quán)的內(nèi)容,請(qǐng)聯(lián)系admin@php.cn
最新問(wèn)題
開(kāi)源免費(fèi)商場(chǎng)系統(tǒng)廣告
最新下載
更多>
網(wǎng)站特效
網(wǎng)站源碼
網(wǎng)站素材
前端模板
關(guān)于我們 免責(zé)申明 意見(jiàn)反饋 講師合作 廣告合作 最新更新
php中文網(wǎng):公益在線php培訓(xùn),幫助PHP學(xué)習(xí)者快速成長(zhǎng)!
關(guān)注服務(wù)號(hào) 技術(shù)交流群
PHP中文網(wǎng)訂閱號(hào)
每天精選資源文章推送
PHP中文網(wǎng)APP
隨時(shí)隨地碎片化學(xué)習(xí)
PHP中文網(wǎng)抖音號(hào)
發(fā)現(xiàn)有趣的

Copyright 2014-2025 http://ipnx.cn/ All Rights Reserved | php.cn | 湘ICP備2023035733號(hào)