婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av

主頁 > 知識庫 > 基于Redis實現分布式鎖的方法(lua腳本版)

基于Redis實現分布式鎖的方法(lua腳本版)

熱門標簽:北京400電話辦理收費標準 鄭州人工智能電銷機器人系統 十堰營銷電銷機器人哪家便宜 日本中國地圖標注 超呼電話機器人 魔獸2青云地圖標注 山東外呼銷售系統招商 貴州電銷卡外呼系統 宿遷便宜外呼系統平臺

1、前言

在Java中,我們通過鎖來避免由于競爭而造成的數據不一致問題。通常我們使用synchronized 、Lock來實現。但是Java中的鎖只能保證在同一個JVM進程內中可用,在跨JVM進程,例如分布式系統上則不可靠了。

2、分布式鎖

分布式鎖,是一種思想,它的實現方式有很多,如基于數據庫實現、基于緩存(Redis等)實現、基于Zookeeper實現等等。為了確保分布式鎖可用,我們至少要確保鎖的實現同時滿足以下四個條件

  • 互斥性:在任意時刻,只有一個客戶端能持有鎖。
  • 不會發生死鎖:即使客戶端在持有鎖的期間崩潰而沒有主動解鎖,也能保證后續其他客戶端能加鎖。
  • 具有容錯性:只要大部分的Redis節點正常運行,客戶端就可以加鎖和解鎖。
  • 解鈴還須系鈴人:加鎖和解鎖必須是同一個客戶端,客戶端自己不能把別人加的鎖給解了。

 3、基于Redis實現分布式鎖

以下代碼實現了基于redis中間件的分布式鎖。加鎖的過程中為了保障setnx(設置KEY)和expire(設置超時時間)盡可能在一個事務中,使用到了lua腳本的方式,將需要完成的指令一并提交到redis中;

3.1、RedisConfig.java

package com.demo.configuration;

import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.data.redis.connection.RedisConnectionFactory;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.serializer.GenericJackson2JsonRedisSerializer;
import org.springframework.data.redis.serializer.StringRedisSerializer;

@Configuration
public class RedisConfig {

    @Bean
    public RedisTemplateString, Object> redisTemplate(RedisConnectionFactory factory) {
        RedisTemplateString, Object> template = new RedisTemplate>();
        template.setConnectionFactory(factory);
        // key采用String的序列化方式
        template.setKeySerializer(new StringRedisSerializer());
        // value序列化方式采用jackson
        template.setValueSerializer(new GenericJackson2JsonRedisSerializer());
        template.afterPropertiesSet();
        return template;
    }

}

3.2、RedisLockController.java

package com.demo.controller;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.io.ClassPathResource;
import org.springframework.data.redis.core.RedisTemplate;
import org.springframework.data.redis.core.script.DefaultRedisScript;
import org.springframework.scripting.support.ResourceScriptSource;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import java.util.Arrays;

@RestController
@RequestMapping("/redis")
public class RedisLockController {

    @Autowired
    private RedisTemplateString, Object> redisTemplate;

    @RequestMapping(value = "/lock/{key}/{uid}/{expire}")
    public Long lock(@PathVariable("key") String key, @PathVariable("uid") String uid, @PathVariable("expire") Integer expire) {
        Long result = null;
        try {
            //調用lua腳本并執行
            DefaultRedisScriptLong> redisScript = new DefaultRedisScript>();
            redisScript.setResultType(Long.class);//返回類型是Long
            //lua文件存放在resources目錄下的redis文件夾內
            redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("redis/redis_lock.lua")));
            result = redisTemplate.execute(redisScript, Arrays.asList(key), uid, expire);
            System.out.println("lock==" + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

    @RequestMapping(value = "/unlock/{key}/{uid}")
    public Long unlock(@PathVariable("key") String key, @PathVariable("uid") String uid) {
        Long result = null;
        try {
            //調用lua腳本并執行
            DefaultRedisScriptLong> redisScript = new DefaultRedisScript>();
            redisScript.setResultType(Long.class);//返回類型是Long
            //lua文件存放在resources目錄下的redis文件夾內
            redisScript.setScriptSource(new ResourceScriptSource(new ClassPathResource("redis/redis_unlock.lua")));
            result = redisTemplate.execute(redisScript, Arrays.asList(key), uid);
            System.out.println("unlock==" + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
        return result;
    }

}

3.3、redis_lock.lua

if redis.call('setnx',KEYS[1],ARGV[1]) == 1 then
    return redis.call('expire',KEYS[1],ARGV[2])
else
    return 0
end

3.4、redis_unlock.lua

if redis.call("exists",KEYS[1]) == 0 then
    return 1
end

if redis.call('get',KEYS[1]) == ARGV[1] then
    return redis.call('del',KEYS[1])
else
    return 0
end

4、測試效果

key123為key,thread12345為value標識鎖的主人,300為該鎖的超時時間

加鎖:鎖主人為thread12345
http://127.0.0.1:8080/redis/lock/key123/thread12345/300

解鎖:解鎖人為thread123456
http://127.0.0.1:8080/redis/unlock/key123/thread123456

解鎖:解鎖人為thread12345
http://127.0.0.1:8080/redis/unlock/key123/thread12345

4.1、加鎖,其他人解鎖


thread12345加的鎖,thread123456是解不了的,只有等thread12345自己解鎖或者鎖的超時時間過期

4.2、加鎖,自己解鎖


thread12345加的鎖,thread12345自己隨時可以解鎖,也可以等鎖的超時時間過期

5、總結

  •  使用Redis鎖,會有業務未執行完,鎖過期的問題,也就是鎖不具有可重入性的特點。
  • 使用Redis鎖,在嘗試獲取鎖的時候,是非阻塞的,不滿足在一定期限內不斷嘗試獲取鎖的場景。
  • 以上兩點,都可以采用Redisson鎖解決。

到此這篇關于基于Redis實現分布式鎖的方法(lua腳本版)的文章就介紹到這了,更多相關Redis實現分布式鎖內容請搜索腳本之家以前的文章或繼續瀏覽下面的相關文章希望大家以后多多支持腳本之家!

您可能感興趣的文章:
  • 詳解redis分布式鎖的這些坑
  • SpringBoot之使用Redis實現分布式鎖(秒殺系統)
  • 詳解Redis 分布式鎖遇到的序列化問題
  • 詳解RedisTemplate下Redis分布式鎖引發的系列問題
  • redisson分布式鎖的用法大全
  • php基于redis的分布式鎖實例詳解
  • Redis分布式鎖升級版RedLock及SpringBoot實現方法
  • 利用redis實現分布式鎖,快速解決高并發時的線程安全問題
  • 詳解基于redis實現分布式鎖

標簽:朝陽 楊凌 大慶 吉安 果洛 江蘇 臺州 北京

巨人網絡通訊聲明:本文標題《基于Redis實現分布式鎖的方法(lua腳本版)》,本文關鍵詞  基于,Redis,實現,分布式,;如發現本文內容存在版權問題,煩請提供相關信息告之我們,我們將及時溝通與處理。本站內容系統采集于網絡,涉及言論、版權與本站無關。
  • 相關文章
  • 下面列出與本文章《基于Redis實現分布式鎖的方法(lua腳本版)》相關的同類信息!
  • 本頁收集關于基于Redis實現分布式鎖的方法(lua腳本版)的相關信息資訊供網民參考!
  • 推薦文章
    婷婷综合国产,91蜜桃婷婷狠狠久久综合9色 ,九九九九九精品,国产综合av
    在线播放欧美女士性生活| 在线观看免费成人| 日本伊人午夜精品| 久久99国内精品| 国产成人精品亚洲午夜麻豆| 一本久久综合亚洲鲁鲁五月天 | 亚洲日本一区二区| 一区二区三区在线不卡| 青青国产91久久久久久| 国产suv一区二区三区88区| 91福利社在线观看| 久久中文字幕电影| 一区二区三区欧美久久| 韩国av一区二区三区在线观看 | 亚洲天堂精品在线观看| 日本系列欧美系列| 成人白浆超碰人人人人| 91超碰这里只有精品国产| 中文字幕av一区二区三区高| 天堂一区二区在线免费观看| 99久久99久久精品免费看蜜桃| 欧美成人高清电影在线| 亚洲一区二区欧美| av毛片久久久久**hd| 精品国产伦一区二区三区观看方式| 亚洲精品va在线观看| 国产盗摄一区二区三区| 欧美一区二区美女| 亚洲综合久久久久| 99精品视频一区| 国产亚洲欧美在线| 日韩福利视频网| 在线观看日韩高清av| 国产精品久久久久四虎| 成人ar影院免费观看视频| 欧美日韩精品高清| 中文字幕制服丝袜成人av| 免费成人你懂的| 欧美做爰猛烈大尺度电影无法无天| 中国av一区二区三区| 久久99国内精品| 欧美精品久久久久久久多人混战| 国产精品传媒在线| 国产精品一区二区三区四区| 欧美一级二级三级乱码| 五月天激情综合网| 在线观看成人免费视频| 成人免费在线播放视频| 国产精品99久| 国产日韩综合av| 老司机精品视频在线| 国内精品在线播放| 日韩欧美国产综合一区| 天天做天天摸天天爽国产一区 | 国内精品免费在线观看| 精品理论电影在线| 美女视频一区在线观看| 3d动漫精品啪啪| 日韩精品亚洲一区| 91麻豆精品国产91久久久久| 亚洲五月六月丁香激情| 欧美日韩一区二区三区四区| 亚洲福中文字幕伊人影院| 日本久久电影网| 亚洲最新视频在线观看| 欧美日韩综合在线| 天堂蜜桃91精品| 91精品久久久久久久99蜜桃| 在线不卡免费av| 亚洲电影在线免费观看| 欧美精品在线一区二区三区| 日本不卡一区二区| 日韩免费福利电影在线观看| 久草这里只有精品视频| 久久久精品综合| 99re热这里只有精品视频| 亚洲综合在线观看视频| 欧美猛男超大videosgay| 日韩精品乱码免费| www激情久久| 亚洲黄色av一区| 欧美一区二区三区四区视频 | 欧美高清性hdvideosex| 欧美aaa在线| 久久精品视频一区| 99re热这里只有精品视频| 亚洲最大成人综合| 日韩三级.com| 不卡的av网站| 婷婷久久综合九色综合伊人色| 欧美一区二区三区啪啪| 国产成人精品一区二区三区网站观看| 1000部国产精品成人观看| 欧美色综合影院| 国产麻豆日韩欧美久久| 一区二区三区欧美视频| 亚洲精品一区二区精华| 99综合电影在线视频| 日本欧美加勒比视频| 国产精品网友自拍| 欧美色精品在线视频| 国内一区二区视频| 亚洲亚洲精品在线观看| 欧美极品另类videosde| 欧美日韩国产精选| 国产成人av一区二区三区在线| 亚洲一区二区偷拍精品| 久久久精品欧美丰满| 欧美天堂亚洲电影院在线播放| 国产综合久久久久影院| 亚洲一区二区3| 国产欧美精品一区二区色综合朱莉| 欧美三级电影网| 波多野结衣欧美| 精品一区二区三区日韩| 亚洲成在线观看| 亚洲欧洲av色图| 久久久三级国产网站| 3d动漫精品啪啪| 欧美在线免费视屏| 成人a区在线观看| 狠狠色综合色综合网络| 日韩精品电影在线| 一区二区视频免费在线观看| 中文字幕精品一区二区三区精品| 欧美一区二区成人| 欧洲生活片亚洲生活在线观看| 国产盗摄一区二区三区| 久久99蜜桃精品| 日韩精品乱码av一区二区| 亚洲色图欧美在线| 国产精品国产三级国产普通话三级| 精品少妇一区二区三区| 欧美一级久久久久久久大片| 欧美三级视频在线| 色综合久久中文综合久久牛| 成人黄色软件下载| 成人免费毛片a| 国产suv一区二区三区88区| 粉嫩13p一区二区三区| 国产精品一级黄| 国产成人综合在线观看| 国产精品影音先锋| 国产精品家庭影院| 中文字幕不卡一区| 国产精品日产欧美久久久久| 中文字幕免费在线观看视频一区| 国产午夜精品久久久久久免费视| 日韩精品一区国产麻豆| 欧美精品一区二区在线播放| 欧美精品一区二区三区久久久| 日韩精品专区在线| 久久久久99精品国产片| 国产欧美一区二区三区在线看蜜臀 | 亚洲男人的天堂一区二区| 国产日韩影视精品| 国产精品久久免费看| 亚洲精品福利视频网站| 亚洲国产欧美日韩另类综合 | 亚洲精品精品亚洲| 亚洲不卡av一区二区三区| 日韩电影在线观看网站| 久久激情综合网| 国产**成人网毛片九色| 91日韩精品一区| 欧美精品粉嫩高潮一区二区| 欧美xxxx老人做受| 国产精品妹子av| 偷偷要91色婷婷| 韩国精品主播一区二区在线观看| www.激情成人| 欧美日韩一区二区在线视频| 成人av电影免费在线播放| 欧美三级三级三级爽爽爽| 日韩欧美自拍偷拍| 国产精品二三区| 五月天欧美精品| 国产超碰在线一区| 欧美视频一区在线观看| 久久这里只有精品6| 亚洲日本免费电影| 久久电影网站中文字幕| 亚洲欧美综合网| 日韩av电影一区| 成人一道本在线| 91麻豆精品国产91久久久久| 国产色爱av资源综合区| 亚洲午夜一区二区| 国产福利视频一区二区三区| 欧美在线|欧美| 色欧美片视频在线观看| 久久综合五月天婷婷伊人| ...av二区三区久久精品| 精品一区二区三区在线播放| 91麻豆精品视频| 亚洲精品在线一区二区| 亚洲bt欧美bt精品| 成人短视频下载| 欧美大胆人体bbbb| 一区二区三区在线观看动漫|