首页 > 其他分享 >分布式锁(设置锁和过期时间)

分布式锁(设置锁和过期时间)

时间:2023-06-05 21:55:18浏览次数:37  
标签:uuid 过期 lock value num 设置 redisTemplate 分布式

问题描述:

随着业务发展的需要,原单体单机部署的系统被演化分成分布式集群系统后,由于分布式系统多线程、多进程且分布在不同机器上,这将使原单机部署情况下的并发控制锁策略失效,单纯的Java API并不能提供分布式锁的能力。为了解决这个问题就需要一种跨JVM的互斥机制来控制共享资源的访问,这就是分布式锁要解决的问题

分布式锁主流的实现方案:

1、基于数据库实现分布式锁

2、基于缓存(Redis等)

3、基于Zookeeper

每一种分布式锁解决方案都有各自的优缺点。

解决方案:基于Redis实现分布式锁

redis:命令

# set sku:1:info "OK" NX PX 10000

EX second:设置键的过期时间为seconds秒,SET key value EX second效果等同于SETEX key second value

NX::只在键不存在时,才对键进行设置操作,SET key value NX效果等同于SETNX key value

XX:只在键已经存在时,才对键进行设置操作

DEL:释放锁

设置过期时间解决锁一直不能释放的问题

上锁之后出现异常无法设置过期时间:上锁时同时设置过期时间 set users 10 nx ex 10   既上锁又设置过期时间同步进行。

 @GetMapping("/testLock")
    public void testLock(){
        //1、获取锁, setnx
        Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", "111", 3, TimeUnit.SECONDS);
        //2、获取锁成功,查询num的值
        if(lock){
            Object value = redisTemplate.opsForValue().get("num");
            //2.1 判断num为空return
            if(StringUtils.isEmpty(value)){
                return;
            }
            //2.2 有值就转成int
            int num = Integer.parseInt(value + "");
            //2。3 把redis的num加1
            redisTemplate.opsForValue().set("num", ++num);
            //2.4 释放锁,del
            redisTemplate.delete("lock");
        }else {
            //3 获取锁失败,每个0.1秒再获取
            try{
                Thread.sleep(100);
                testLock();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }

存在问题:误删,锁释放错了

a:先操作

1、上锁

2、具体操作

服务器卡顿

3、锁自动释放

b:抢到锁,具体操作

a服务器反应过来,进行操作,手动释放锁,释放了b的锁

方法:使用UUID表示不同操作

1、set lock uuid nx ex 10

2、释放锁时,首先判断当前uuid和要释放锁的uuid是否一样。

 @GetMapping("/testLock")
    public void testLock(){
        String uuid = UUID.randomUUID().toString();
        //1、获取锁, setnx
        Boolean lock = redisTemplate.opsForValue().setIfAbsent("lock", uuid, 3, TimeUnit.SECONDS);
        //2、获取锁成功,查询num的值
        if(lock){
            Object value = redisTemplate.opsForValue().get("num");
            //2.1 判断num为空return
            if(StringUtils.isEmpty(value)){
                return;
            }
            //2.2 有值就转成int
            int num = Integer.parseInt(value + "");
            //2。3 把redis的num加1
            redisTemplate.opsForValue().set("num", ++num);
            //2.4 释放锁,del、判断比较uuid是否一样
            if(redisTemplate.opsForValue().get("lock").equals(uuid)){
                redisTemplate.delete("lock");
            }
            
        }else {
            //3 获取锁失败,每个0.1秒再获取
            try{
                Thread.sleep(100);
                testLock();
            }catch(InterruptedException e){
                e.printStackTrace();
            }
        }
    }

 

标签:uuid,过期,lock,value,num,设置,redisTemplate,分布式
From: https://www.cnblogs.com/fxzm/p/17459023.html

相关文章

  • fastadmin设置列表页快捷搜索输入框内的文字placeholder
     找到对应的列表js文件,在bootstrapTable初始化前增加这么一段代码:$.fn.bootstrapTable.locales[Table.defaults.locale]['formatSearch']=function(){return"渠道名称或业务城市";}; 比如这里要搜索的是渠道名称或者业务城市,前提是数据表有这些字段,那么就......
  • Vue3 setup语法糖下的axios全局设置教程
    Vue3setup语法糖下的axios全局设置教程前言在Vue3的组件式API开发下,this关键词不再适用,网上很多配置axios教程都是以Vue2为基础的,在Vue3下不再适用。近期尝试用组件式API风格写项目,在配置全局axios就遇到了这个问题。经过我反复尝试,查阅官网的文档,终于有了以下解决方法:Vue2......
  • 电脑WIFI无法连接5gwifi设置
    1.找到网络连接对应wifi 右键点选配置,然后高级 2.到了这一步可以看到我这里的属性只有3个,点击WirelessMode 3.选802.11a就行了因为无线规格工作频段802.11a(5GHz)802.11b(2.4GHz)802.11g(2.4GHz)802.11n(2.4/5GHz)802.11ac(2.4/5GHz)  4.再不行(比如高级->属性这里......
  • Linux和Mac环境变量设置
    在linux和mac中设置环境变量我已知的有两种方式,一种是修改环境变量的文件,另一种是使用export关键字。之所以不提windows,是因为我所知的在windows上配置环境变量只有通过窗口然后点击这一种方式。以mac配置pyenv环境变量为例:1、export方式查看当前shell是zsh还是bash,如果是bas......
  • 分布式爬虫
    分布式分布式的本质就如上期提到的一个概念:分布式系统是若干独立计算机的集合,这些计算机对于用户来说就像是单个相关系统。这就是在说,把廉价的计算机堆到一起,通过程序控制,使其整体用起来像个高性能计算机,目的就是节约成本。对于分布式爬虫系统来说,假设1台机器能10天爬完一个任务......
  • Windows AD域查询属性-密码过期时间
    WindowsAD域查询属性-密码过期时间WindowsPowerShell命令方式查询:netuserzhou/domain找出SamAccountName的值为zhou的用户部分信息PSC:\user\admin>netuserzhou/domainUsernamezhouFullnamezhouCommentUser'scomment......
  • 分布式和为服务区别
    微服务介绍(史上最全)答疑|分布式和微服务的区别?   ......
  • Springboot 链接DataSource前检查或创建库,并设置时区及sql_mode
    /**Copyright(c)2022.AsiacomTechnologyInc.Allrightsreserved*/importorg.slf4j.Logger;importorg.slf4j.LoggerFactory;importorg.springframework.beans.factory.annotation.Value;importorg.springframework.context.annotation.Configuration;......
  • Hadoop伪分布式安装
    Hadoop伪分布式安装安装环境:Centos7.5,只少2核4G提前准备:Linux中要安装JDK8,Zookeeper-3.5.71.关闭防火墙systemctlstopfirewalldsystemctldisablefirewalld2.修改主机名Hadoop集群中,主机名中尽量不要出现-或者_vim/etc/hostname将原来的主机名删除,添加自己指定的主机名3.需......
  • 【获奖案例巡展】信创先锋之星——江西金发基于分布式数据库的互联网金融业务系统
    为表彰使用大数据、人工智能等基础软件为企业、行业或世界做出杰出贡献和巨大创新的标杆项目,星环科技自2021年推出了“新科技星力量”星环科技科技实践案例评选活动,旨在为各行业提供更多的优秀产品案例,彰显技术改变世界的力量,目前已成功举办两届,收到了来自各界的积极参与。 第二......