Error message here!

Hide Error message here!

忘记密码?

Error message here!

请输入正确邮箱

Hide Error message here!

密码丢失?请输入您的电子邮件地址。您将收到一个重设密码链接。

Error message here!

返回登录

Close

基于redis的分布式锁实现方案--redisson

<虎口脱险> 2019-01-25 17:08:00 阅读数:134 评论数:0 点赞数:0 收藏数:0

实例代码地址,请前往:https://gitee.com/GuoqingLee/distributed-seckill

redis官方文档地址,请前往:http://www.redis.cn/topics/distlock.html

前言

关于分布式锁的实现,目前主流方案有以下三类:

1、基于数据库的乐观锁;

2、基于redis实现的锁服务;

3、基于zookeeper的实现;

网上关于怎么实现redis的分布式锁,一搜一大把的文章,有写的比较好的,也有明显存在缺陷的,非常容易误导初入这一块的初学者;

而存在的问题,无外乎是setnx()-->expire(),保证不了原子性,容易出现死锁等情况,这里就不在去做解释了;

本文的主旨是如何使用redis官方推荐的redisson实现redis的分布式锁;

一、具体实现:

maven引入需要的jar

1 <dependency>
2 <groupId>org.redisson</groupId>
3 <artifactId>redisson-spring-boot-starter</artifactId>
4 <version>3.10.1</version>
5 </dependency>

配置文件如下

# common spring boot settings
spring.redis.database=
spring.redis.host=
spring.redis.port=
spring.redis.password=
spring.redis.ssl=
spring.redis.timeout=
spring.redis.cluster.nodes=
spring.redis.sentinel.master=
spring.redis.sentinel.nodes=

封装工具类:

 1 package cn.com.bluemoon.redis.lock;
 2
 3 import java.util.concurrent.TimeUnit;
 4
 5 import org.redisson.api.RLock;
 6 import org.redisson.api.RedissonClient;
 7 import org.springframework.beans.factory.annotation.Autowired;
 8 import org.springframework.stereotype.Component;
 9
 10 /**
 11  * 基于Redisson的分布式锁实现
 12  * @author Guoqing.Lee
 13  * @date 2019年1月23日 下午4:04:57
 14  *
 15 */
 16 @Component
 17 public class RedissonDistributedLocker {
 18
 19  @Autowired
 20 private RedissonClient redissonClient;
 21
 22 /**
 23  * 加锁
 24  * @param lockKey
 25  * @return
 26 */
 27 public RLock lock(String lockKey) {
 28 RLock lock = redissonClient.getLock(lockKey);
 29  lock.lock();
 30 return lock;
 31  }
 32
 33 /**
 34  * 加锁,过期自动释放
 35  * @param lockKey
 36  * @param leaseTime 自动释放锁时间
 37  * @return
 38 */
 39 public RLock lock(String lockKey, long leaseTime) {
 40 RLock lock = redissonClient.getLock(lockKey);
 41  lock.lock(leaseTime, TimeUnit.SECONDS);
 42 return lock;
 43  }
 44
 45 /**
 46  * 加锁,过期自动释放,时间单位传入
 47  * @param lockKey
 48  * @param unit 时间单位
 49  * @param leaseTime 上锁后自动释放时间
 50  * @return
 51 */
 52 public RLock lock(String lockKey, TimeUnit unit, long leaseTime) {
 53 RLock lock = redissonClient.getLock(lockKey);
 54  lock.lock(leaseTime, unit);
 55 return lock;
 56  }
 57
 58 /**
 59  * 尝试获取所
 60  * @param lockKey
 61  * @param unit 时间单位
 62  * @param waitTime 最多等待时间
 63  * @param leaseTime 上锁后自动释放时间
 64  * @return
 65 */
 66 public boolean tryLock(String lockKey, TimeUnit unit, long waitTime, long leaseTime) {
 67 RLock lock = redissonClient.getLock(lockKey);
 68 try {
 69 return lock.tryLock(waitTime, leaseTime, unit);
 70 } catch (InterruptedException e) {
 71 return false;
 72  }
 73  }
 74
 75 /**
 76  * 尝试获取所
 77  * @param lockKey
 78  * @param waitTime 最多等待时间
 79  * @param leaseTime 上锁后自动释放锁时间
 80  * @return
 81 */
 82 public boolean tryLock(String lockKey, long waitTime, long leaseTime) {
 83 RLock lock = redissonClient.getLock(lockKey);
 84 try {
 85 return lock.tryLock(waitTime, leaseTime, TimeUnit.SECONDS);
 86 } catch (InterruptedException e) {
 87 return false;
 88  }
 89  }
 90
 91 /**
 92  * 释放锁
 93  * @param lockKey
 94 */
 95 public void unlock(String lockKey) {
 96 RLock lock = redissonClient.getLock(lockKey);
 97  lock.unlock();
 98  }
 99
100 /**
101  * 释放锁
102  * @param lock
103 */
104 public void unlock(RLock lock) {
105  lock.unlock();
106  }
107
108 }

二、使用方式

方式一:

 1  @Autowired
 2 private RedissonDistributedLocker redissonDistributedLocker;
 3
 4 String lockKey = "BM_MARKET_SECKILL_" + stallActivityId;
 5 try {
 6 //超过2S自动释放锁
 7 redissonDistributedLocker.lock(lockKey, 2L);
 8 //业务处理
 9
10 } finally {
11 redissonDistributedLocker.unlock(lockKey); //释放锁
12 } 

方案二:

 1 @Autowired
 2 private RedissonDistributedLocker redissonDistributedLocker;
 3
 4 public void test() throws InterruptedException {
 5 final int[] counter = {0};
 6
 7 for (int i= 0; i < 100; i++){
 8
 9 new Thread(new Runnable() {
10
11  @Override
12
13 public void run() {
14 boolean isGetLock = redissonDistributedLocker.tryLock("test0001", 3L, 1L);
15 if(isGetLock) {
16 try {
17 int a = counter[0];
18 counter[0] = a + 1;
19 logger.info(a + "");
20 } finally {
21 redissonDistributedLocker.unlock("test0001");
22  }
23  }
24  }
25  }).start();
26
27  }
28
29 // 主线程休眠,等待结果
30 Thread.sleep(5000);
31 System.out.println(counter[0]);
32 logger.info(counter[0] + "");
33 }

闲话就不多说了,希望能对你有所帮助。

 

版权声明
本文为[<虎口脱险>]所创,转载请带上原文链接,感谢
https://www.cnblogs.com/ocean-sky/p/10320627.html

编程之旅,人生之路,不止于编程,还有诗和远方。
阅代码原理,看框架知识,学企业实践;
赏诗词,读日记,踏人生之路,观世界之行;