Redisson 的分布式锁
参考:https://www.cnblogs.com/zgq7/p/14746128.html
一、Redisson 的使用
1、Redisson 的简单使用
(1)引入maven坐标;
<dependency> <groupId>org.redisson</groupId> <artifactId>redisson-spring-boot-starter</artifactId> <version>3.13.4</version> </dependency>
(2)增加配置文件,将Redisson注入到容器中;
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 | @Configuration public class RedissonConfig { @Bean public Redisson redisson() { Config config = new Config(); //单机版 //config.useSingleServer().setAddress("redis://192.168.1.1:8001").setDatabase(0); //集群版 config.useClusterServers() .addNodeAddress( "redis://192.168.1.1:8001" ) .addNodeAddress( "redis://192.168.1.1:8002" ) .addNodeAddress( "redis://192.168.1.2:8001" ) .addNodeAddress( "redis://192.168.1.2:8002" ) .addNodeAddress( "redis://192.168.1.3:8001" ) .addNodeAddress( "redis://192.168.1.3:8002" ); return (Redisson) Redisson.create(config); } } |
(3)分布式锁的实现
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 | @Service public class RedisLockDemo { @Autowired private StringRedisTemplate redisTemplate; @Autowired private Redisson redisson; public String deduceStock() { String lockKey = "lockKey" ; RLock redissonLock = redisson.getLock(lockKey); try { //加锁, 实现锁续命的功能(加锁成功,后台启动一个timer, 默认每10s检测一次是否持有锁,若持有锁则继续续命30s) redissonLock.lock(); //------ 执行业务逻辑 ----start------ int stock = Integer.valueOf(redisTemplate.opsForValue().get( "stock" )); if (stock > 0 ) { int newStock = stock - 1 ; //执行业务操作减库存 redisTemplate.opsForValue().set( "stock" , newStock + "" ); System.out.println( "扣减库存成功, 剩余库存:" + newStock); } else { System.out.println( "库存已经为0,不能继续扣减" ); } //------ 执行业务逻辑 ----end------ } finally { //解锁 redissonLock.unlock(); } return "success" ; } } |
2、Redisson 的几种加锁方式
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 | /* * (1) T1加锁成功: 会添加TimerTask; 每10s执行一次检测锁是否为当前线程占用, 若占用, 则将key超时时间重置为30s; * (2) T2加锁失败后会不停的去重试; */ redissonLock.lock(); /* * (1) T1加锁成功后直接返回, 20s后锁自动过期; (没有watch dog) * (2) T2加锁失败后会不停的去重试; */ redissonLock.lock( 20 , TimeUnit.SECONDS); /* * (1) T1尝试加锁成功, 返回true; 会添加TimerTask; 每10s执行一次检测锁是否为当前线程占用, 若占用, 则将key超时时间重置为30s; * (2) T2没有获取到锁会不停的去重试, 在50s后停止重试, 返回false; */ boolean isGetLock = redissonLock.tryLock( 50 , TimeUnit.SECONDS); /* * (1) T1尝试加锁成功, 返回true, 锁在20s后自动过期; (没有watch dog) * (2) T2尝试加锁失败, 在50s后停止重试, 返回false; */ boolean isGetLock = redissonLock.tryLock( 50 , 20 , TimeUnit.SECONDS); //------------------------------------------------------------- //2. 公平锁 保证 Redisson 客户端线程将以其请求的顺序获得锁 RLock fairLock = redissonClient.getFairLock( "fairLock" ); //3. 读写锁 没错与JDK中ReentrantLock的读写锁效果一样 RReadWriteLock readWriteLock = redissonClient.getReadWriteLock( "readWriteLock" ); readWriteLock.readLock().lock(); readWriteLock.writeLock().lock(); |
二、Redisson 的分布式锁原理
Redisson 的加锁和解锁都通过 lua 脚本来处理的;
三、Redisson的分布式锁源码分析
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· Manus重磅发布:全球首款通用AI代理技术深度解析与实战指南
· 被坑几百块钱后,我竟然真的恢复了删除的微信聊天记录!
· 没有Manus邀请码?试试免邀请码的MGX或者开源的OpenManus吧
· 园子的第一款AI主题卫衣上架——"HELLO! HOW CAN I ASSIST YOU TODAY
· 【自荐】一款简洁、开源的在线白板工具 Drawnix
2017-03-09 eclipse中导入dtd文件实现xml的自动提示功能