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

Redis對批量數(shù)據(jù)實(shí)現(xiàn)分布式鎖的實(shí)現(xiàn)代碼

 更新時(shí)間:2022年03月24日 09:46:10   作者:HCAN  
為了防止多人多電腦同時(shí)操作一條數(shù)據(jù),我們自己開發(fā)了一個(gè)簡單的基于Redis實(shí)現(xiàn)的分布式鎖,Redis對批量數(shù)據(jù)實(shí)現(xiàn)分布式鎖相關(guān)知識感興趣的朋友一起看看吧

需求背景

在開發(fā)的收入結(jié)轉(zhuǎn)平臺界面上有一個(gè)歸集按鈕,可以實(shí)現(xiàn)抓取結(jié)轉(zhuǎn)表里面的多條數(shù)據(jù)進(jìn)行歸集操作。為了防止多人多電腦同時(shí)操作一條數(shù)據(jù),我們自己開發(fā)了一個(gè)簡單的基于Redis實(shí)現(xiàn)的分布式鎖。

代碼實(shí)現(xiàn)

邏輯代碼中的使用案例

參數(shù)說明:

scIds:結(jié)轉(zhuǎn)數(shù)據(jù)的ID主鍵集合。

timeOutToDeleteRedisKey:最大鎖超時(shí)時(shí)間(用于自動解鎖)

organizationId:租戶ID(這個(gè)參數(shù)根據(jù)情況選擇是否需要)

ReturnLock returnLock = RedisLock.applyByIds(scIds, redisLockTime, organizationId, () -> {
    // dothing 具體的代碼業(yè)務(wù)邏輯
    return 123;
});
 
if (!returnLock.getFlag()) {
    if(returnLock.getLock()){
        throw new CommonException("歸集數(shù)據(jù)有程序正在運(yùn)行,請稍候刷新頁面重試");
    }else {
        throw new CommonException(returnLock.getErrorMsg());
    }
}
// 返回對象
System.out.println(returnLock.getResObj()) // 123

Redis加鎖方法封裝

public static ReturnLock applyByIds(List<Long> scIds, Long timeOutToDeleteRedisKey, Long tenantId,
                                    Supplier<Object> supplier) {
    // 獲得鎖
    Map<String, String> keyMap = getLockByIds(scIds, timeOutToDeleteRedisKey, tenantId);
    ReturnLock returnLock = new ReturnLock();
    returnLock.setFlag(true);
    returnLock.setLock(false);
    try {
        // 判斷主鍵ID數(shù)量和加鎖的數(shù)量是否一致,不一致說明有加鎖失敗的數(shù)據(jù),返回失敗鎖信息
        if(scIds.size() > keyMap.size()){
            returnLock.setFlag(false);
            returnLock.setLock(true);
            returnLock.setKeyMap(keyMap);
            return returnLock;
        }
        // 應(yīng)用代碼執(zhí)行后的返回結(jié)果 supplier:java8四大內(nèi)置函數(shù)的供給型接口
        // Supplier<T>(供給型接口)無參數(shù),返回類型為T的對象:T get()
        returnLock.setResObj(supplier.get());
    }catch (Exception e) {
        returnLock.setFlag(false);
        returnLock.setErrorMsg(e.getMessage());
        e.printStackTrace();
    }finally {
        // 應(yīng)用代碼執(zhí)行報(bào)錯(cuò),解鎖
        unLockByIds(keyMap);
    }
    return returnLock;
}

getLockByIds

批量獲取每一條數(shù)據(jù)的Redis鎖

private static Map<String, String> getLockByIds(List<Long> scIds, Long timeOutToDeleteRedisKey, Long tenantId) {
    Map<String, String> keyMap = new HashMap<>();
    // 從spring上下文中獲取Redis的操作對象,因?yàn)檫@個(gè)代碼是寫在util中,所以通過上下文方式獲取bean對象
    // RedisHelper:Redis的操作對象,我們自己公司基于redisTemplate封裝的
    RedisHelper redisHelper = SpringUtil.getBean(RedisHelper.class);
    try {
        if (CollectionUtil.isNotEmpty(scIds)) {
            for (int i = 0; i < scIds.size(); i++) {
                String item = "L_" + scIds.get(i);
                String UUID = UUIDUtils.generateTenantUUID(tenantId);
                // 判斷key值是否被鎖,如果沒有鎖則加鎖并設(shè)置過期時(shí)間, 如果有鎖, 則報(bào)錯(cuò)并立即釋放已加的鎖
                // strSetIfAbsent會返回true/false,底層是封裝了java的setIfAbsent方法和Redis的setnx方法
                // 如果設(shè)置成功返回true否則false
                if (redisHelper.strSetIfAbsent(item, UUID)) {
                    // 設(shè)置過期時(shí)間
                    redisHelper.setExpire(item, timeOutToDeleteRedisKey, TimeUnit.SECONDS);
                    // 保存設(shè)置的鎖信息
                    keyMap.put(item, UUID);
                } else {
                    // 鎖設(shè)置異常,表示有數(shù)據(jù)被鎖住了,解鎖之間加鎖的數(shù)據(jù)
                    if (MapUtil.isNotEmpty(keyMap)) {
                        if (unLockByIds(keyMap)) {
                            // 解鎖失敗再次解鎖
                            unLockByIds(keyMap);
                        }
                    }
                    // 返回鎖信息
                    return keyMap;
                }
            }
        }
        return keyMap;
    }catch (Exception e) {
        e.printStackTrace();
    }
}

解鎖

private static Boolean unLockByIds(Map<String, String> keyMap) {
    RedisHelper redisHelper = SpringUtil.getBean(RedisHelper.class);
    try {
        if (MapUtil.isEmpty(keyMap)) {
            return false;
        }
        // 判斷是否是自己的鎖
        for (String key : keyMap.keySet()) {
            String uuid = keyMap.get(key);
            if (StringUtils.equals(uuid, redisHelper.strGet(key))) {
                // 封裝了redisTemplate.delete(key);
                redisHelper.delKey(key);
            }
        return true;
    }catch (Exception e) {
        e.printStackTrace();
        return false;
    }
}

實(shí)現(xiàn)效果

當(dāng)對數(shù)據(jù)進(jìn)行批量加鎖的時(shí)候,若在加鎖的過程中出現(xiàn)加鎖失敗,則回滾直接加的鎖,并提示"歸集數(shù)據(jù)有程序正在運(yùn)行,請稍候刷新頁面重試"。

若業(yè)務(wù)代碼邏輯執(zhí)行成功或者執(zhí)行報(bào)錯(cuò)都會自動的解鎖當(dāng)前加鎖的數(shù)據(jù)。

到此這篇關(guān)于利用Redis對批量數(shù)據(jù)實(shí)現(xiàn)分布式鎖的文章就介紹到這了,更多相關(guān)Redis分布式鎖內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!

相關(guān)文章

  • Linux Redis 的安裝步驟詳解

    Linux Redis 的安裝步驟詳解

    這篇文章主要介紹了 Linux Redis 的安裝步驟詳解的相關(guān)資料,希望大家通過本文能掌握如何安裝Redis,需要的朋友可以參考下
    2017-08-08
  • Redis?key的過期時(shí)間和永久有效的實(shí)現(xiàn)

    Redis?key的過期時(shí)間和永久有效的實(shí)現(xiàn)

    在Redis中,鍵可以設(shè)置過期時(shí)間或被永久保存,`EXPIRE`和`PEXPIRE`命令分別用于設(shè)置鍵的過期時(shí)間,具有一定的參考價(jià)值,感興趣的可以了解一下
    2024-09-09
  • 詳解如何在YAML文件中配置Redis

    詳解如何在YAML文件中配置Redis

    在現(xiàn)代軟件開發(fā)中,配置文件是非常重要的一部分,其中,YAML(YAML Ain't Markup Language)是一種常用的配置文件格式,具有可讀性強(qiáng)、易于理解和編寫的特點(diǎn),在本篇文章中,我們將探討如何在YAML文件中配置Redis,需要的朋友可以參考下
    2024-09-09
  • Redis消息隊(duì)列、阻塞隊(duì)列、延時(shí)隊(duì)列的實(shí)現(xiàn)

    Redis消息隊(duì)列、阻塞隊(duì)列、延時(shí)隊(duì)列的實(shí)現(xiàn)

    Redis是一種常用的內(nèi)存數(shù)據(jù)庫,它提供了豐富的功能,通常用于數(shù)據(jù)緩存和分布式隊(duì)列,本文主要介紹了Redis消息隊(duì)列、阻塞隊(duì)列、延時(shí)隊(duì)列的實(shí)現(xiàn),感興趣的可以了解一下
    2023-11-11
  • 解決Redis連接無法正常釋放的問題

    解決Redis連接無法正常釋放的問題

    這篇文章主要介紹了解決Redis連接無法正常釋放的問題,具有很好的參考價(jià)值,希望對大家有所幫助。一起跟隨小編過來看看吧
    2020-12-12
  • redis實(shí)現(xiàn)存儲帖子的點(diǎn)贊狀態(tài)和數(shù)量的示例代碼

    redis實(shí)現(xiàn)存儲帖子的點(diǎn)贊狀態(tài)和數(shù)量的示例代碼

    使用Redis來實(shí)現(xiàn)點(diǎn)贊功能是一種高效的選擇,因?yàn)镽edis是一個(gè)內(nèi)存數(shù)據(jù)庫,適用于處理高并發(fā)的數(shù)據(jù)操作,這篇文章主要介紹了redis實(shí)現(xiàn)存儲帖子的點(diǎn)贊狀態(tài)和數(shù)量的示例代碼,需要的朋友可以參考下
    2023-09-09
  • Redis分布式鎖如何實(shí)現(xiàn)續(xù)期

    Redis分布式鎖如何實(shí)現(xiàn)續(xù)期

    這篇文章主要介紹了Redis分布式鎖如何實(shí)現(xiàn)續(xù)期的操作,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2022-01-01
  • Redis監(jiān)控工具RedisInsight安裝與使用

    Redis監(jiān)控工具RedisInsight安裝與使用

    這篇文章主要為大家介紹了Redis監(jiān)控工具RedisInsight的安裝步驟與使用方法,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步
    2022-03-03
  • 帶你輕松掌握Redis分布式鎖

    帶你輕松掌握Redis分布式鎖

    這篇文章主要介紹了帶你輕松掌握Redis分布式鎖,具有很好的參考價(jià)值,希望對大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教
    2021-11-11
  • Redis主從復(fù)制操作和配置詳情

    Redis主從復(fù)制操作和配置詳情

    這篇文章主要介紹了Redis主從復(fù)制操作和配置詳情,文章通過圍繞主題展開詳細(xì)的內(nèi)容介紹,具有一定的參考價(jià)值,需要的小伙伴可以參考一下
    2022-09-09

最新評論

临沭县| 萍乡市| 郁南县| 长岭县| 清丰县| 南部县| 普安县| 盐亭县| 景洪市| 石渠县| 德格县| 尚志市| 汽车| 和政县| 堆龙德庆县| 桂林市| 阳泉市| 榆社县| 西宁市| 余姚市| 酒泉市| 兰溪市| 梧州市| 运城市| 赣榆县| 大关县| 柳河县| 班戈县| 阳谷县| 南昌市| 平舆县| 汽车| 客服| 巴东县| 手机| 伊宁县| 安阳市| 武隆县| 肃北| 突泉县| 惠安县|