Redisson 分布式锁简单应用
RLock rLock = redissonClient.getLock("lockName");// 可以看做是获取一个连接try {// 尝试加锁 愿意等待的时长 waitTime ; 加锁成功后自动释放锁的时长 leaseTime,大于0时不论加锁业务是否处理完毕都会释放锁 boolean locked = rLock.tryLock(1000, 2000, TimeUnit.MILLISECONDS);// 尝试加锁if(locked){// todo 加锁成功需要处理的业务处理}else{// todo 加锁失败需要处理的业务}}catch (Exception e) {// throw e; // 加锁失败 和 业务处理失败后 需要做的事情} finally {try{rLock.unlock();// 这个很要命 手动释放锁 unlock 异常后是否需要}catch(Exception e){// 释放锁失败 要做的处理(忽略异常 还是 继续抛出异常,还是 强制释放锁) }}
上边代码简单说明(重要的事情提前说明):
1、 boolean locked = rLock.tryLock(10000L, -1, TimeUnit.MILLISECONDS); // 假如主线程执行到这里出现某种未知原因,主线程中断了,但是加锁的子线程竟然成功然后并启动看门狗自动延期锁; 2、 rLock.unlock();// 主线程挂掉时子线程加锁没有完成,这里释放锁无效;死锁了。 怎么办? 幸好有 forceUnlock rLock.forceUnlock(); // 强制释放锁 怎么用?什么场景下使用(程序中怎么判断死锁了)?
一、先做点解释
1、参数
waitTime 为了获取锁愿意等待的时长 <= 0 不愿意等待,即没有获取到锁时直接返回false
leaseTime 加锁成功后自动释放锁的时长:
>0 时 不论锁定的业务是否执行完毕都会在这个时间到期时释放锁---这个很要命(一定不会死锁);肯能会存在线程1执行业务没有完毕,锁自动释放了,线程2获取到锁执行了业务,锁失效了;
=-1表示这个锁不会自动释放必须手动释放(可能会死锁),看门狗每10秒(默认配置)延期一次锁(实际是重置锁的过期时间为30秒:默认配置)
2、上图伪代码仅供参考
二、结论
1、根据自身业务 谨慎并合理设置 waitTime 和 leaseTime 值 ;
2、finally 中一定要 手动释放锁 rLock.unlock(); ---锁定的资源在业务处理完毕后尽快释放,不论是否设置了自动释放锁;
三、加锁的lua脚本
"if (redis.call('exists', KEYS[1]) == 0) then " +
"redis.call('hincrby', KEYS[1], ARGV[2], 1); " +
"redis.call('pexpire', KEYS[1], ARGV[1]); " +
"return nil; " +
"end; " +
"if (redis.call('hexists', KEYS[1], ARGV[2]) == 1) then " +
"redis.call('hincrby', KEYS[1], ARGV[2], 1); " +
"redis.call('pexpire', KEYS[1], ARGV[1]); " +
"return nil; " +
"end; " +
"return redis.call('pttl', KEYS[1]);"
KEYS[1]=lockName,ARGV[2]=hash中的key=redisson客户端节点id+线程id,ARGV[1]=锁的过期时间
四、记录一个问题:
执行加锁时遇到一个异常 WRONGTYPE Operation against a key holding the wrong kind of value
具体异常信息:
org.redisson.client.RedisException: WRONGTYPE Operation against a key holding the wrong kind of value.
channel: [xxxx]
command: (HEXISTS), params: [LOCK_NAME, XXXXX]
发生问题的地方:执行加锁脚本走都第二个分支时 执行 redis.call('hexists', KEYS[1], ARGV[2]) == 1 命令有redis服务端抛出异常;
原因:针对LOCK_NAME ,服务1 中使用了 redisson 的锁,服务2中 程序员自己实现了一个分布式锁;
结论:不要制造不必要的轮子
Redisson 分布式锁简单应用相关推荐
- Redisson分布式锁简单应用
目录 1.业务场景 2.解决方案 方案一:数据库存储字段设置为唯一 方案二:使用分布式锁 3.应用实例 1.引入依赖 2.配置redisson 3.使用分布式锁 1.获取锁对象 2.获取分布式锁 3. ...
- Redisson分布式锁实战-1:构建分布式锁
我们现在来到Task类当中,这个方法就是V4了/*** Redisson分布式锁实现* @throws InterruptedException*/ // @Scheduled(cron=" ...
- 年轻人,看看 Redisson 分布式锁—可重入锁吧!太重要了
作者 | 李祥 责编 | 张文 来源 | 企鹅杏仁技术站(ID:xingren-tech) 引言 作为后端开发,对于所谓的线程安全.高并发等一系列名词肯定都不会陌生,相关的一些概念及技术框架是面 ...
- springboot基础(72):Redisson分布式锁
文章目录 前言 第一节 入门使用Redisson 第二节 注解形式的分布式锁 1. 分布式锁的注解实现 2. 分析MyRedissonLock注解和使用 传送门 前言 并发执行是比较场景的场景,单机情 ...
- redis ,redisson 分布式锁深入剖析
目录 为什么要用分布式锁? 分布式锁所遵循的原则? redis 分布式锁 redis 原始分布式锁实现 加锁 释放锁 redis 分布式锁存在的问题 redisson 实现分布式锁 redisson ...
- Redis实战——Redisson分布式锁
目录 1 基于Redis中setnx方法的分布式锁的问题 2 Redisson 2.1 什么是Redisson 2.2 Redisson实现分布式锁快速入门 2.3 Redisson 可重入锁原理 什 ...
- redisson分布式锁,实战
目录 什么时候用分布式锁? 分布式锁入门 超时设置 释放了不是自己加的锁 正确设置锁超时 加解锁代码位置有讲究 实现可重入锁 Redis Hash 可重入锁 主从架构带来的问题 什么是 Redlock ...
- Redis:Redisson分布式锁的使用(推荐使用)
Redis:Redisson分布式锁的使用(生产环境下)(推荐使用) 关键词 基于NIO的Netty框架,生产环境使用分布式锁 redisson加锁:lua脚本加锁(其他客户端自旋) 自动延时机制:启 ...
- 年轻人,看看Redisson分布式锁—可重入锁吧!太重要了
1.引言 作为后端开发,对于所谓的线程安全.高并发等一系列名词肯定都不会陌生,相关的一些概念及技术框架是面试中的宠儿,也是工作中解决一些特定场景下的技术问题的银弹.今天我们就来聊聊这些银弹中的其中一枚 ...
最新文章
- mysql服务怎么改名字_MySQL数据库改名字
- 双击.exe文件出现Debug Error: abort() has been called解决办法(之一)
- 简述C语言的标准发展,简述C语言的发展历史
- Python正则表达式re模块简明笔记
- 【Bugly 技术干货】Android开发必备知识:为什么说Kotlin值得一试
- 20220130---CTF WEB方向---命令执行和URL解码
- 最大乘积(记忆化搜索)
- win8消费者预览版Chrome无法设置默认浏览器
- Widows核心编程第一章:错误处理
- hbuilder能用python_Hbuilder之开发Python
- MSSQL 同步两个数据库的示例
- NEON码农指导 Chapter 3 : NEON Instruction Set Architecture
- matlab 柯西黎曼方程,解析函数及柯西黎曼方程.ppt
- Word大括号多行公式左对齐
- MySQL的三个锁级别(附图)
- Amy-Tabb机器人世界手眼标定(1、环境搭配)
- 微信点餐html5模板,【瑞蚁原创分享】12:springboot微信点餐之微信模板
- Android案例手册 - 实现一个华容道拼图游戏
- RPGMAKER游戏引擎基于JavaScript的插件制作(六)——重写方法(三):在场景(scenes)中创建精灵(Sprite)——复制式重写的实例教学
- 【网络编程】大端模式和小端模式