当一个业务执行时间超过自己设定的锁释放时间,那么会导致有其他线程进入,从而抢到同一个票,所有需要使用看门狗策略,其实就是开一个守护线程,让守护线程去监控key,如果到时间了还未结束,就会将这个key重新set一次,重置到原来的时间,只要主线程未结束,守护线程就会一直存在,这里还是会有一些问题,就是如果redis宕机了,导致第一个线程拿到了锁,第二个线程也拿到了锁,为了解决这个就需要引入红锁
1. 导入依赖,这里导入依赖可能会和原先的redis依赖冲突,所以只能留下一个,不然可能会出错
去除spring-boot-starter-data-redis- <!-- 集成Redis-->
- <dependency>
- <groupId>org.springframework.boot</groupId>
- <artifactId>spring-boot-starter-data-redis</artifactId>
- </dependency>
复制代码 添加redisson- <dependency>
- <groupId>org.redisson</groupId>
- <artifactId>redisson-spring-boot-starter</artifactId>
- <version>3.21.0</version>
- </dependency>
复制代码 2. 修改配置文件,将之前的配置缓存redisson的- spring:
- data:
- redis: # redis配置
- url: redis://:127.0.0.1:6379
复制代码 3. 开始分布式锁-看门狗策略,找到高频访问的业务添加以下代码
在业务方法开始的头添加
在方法末尾添加释放锁,别忘了添加try-catch-finally块
这是一段完整的分布式处理,有需要直接copy后修改即可- public void doConfirm(ConfirmOrderDoReq req) {
- String lockKey = DateUtil.formatDate(req.getDate()) + "-" + req.getTrainCode();
- RLock lock = null;
- try {
- lock = redissonClient.getLock(lockKey);
- boolean tryLock = lock.tryLock(0, TimeUnit.SECONDS);
- if (tryLock) {
- LOG.info("抢到锁,开始处理订单");
- } else {
- LOG.info("很遗憾,没有抢到锁");
- //当前抢票人数多,请稍后再试
- throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_LOCK_FAIL);
- }
- //业务处理。。。。
- } catch (InterruptedException e) {
- LOG.error("抢票失败", e);
- throw new BusinessException(BusinessExceptionEnum.CONFIRM_ORDER_LOCK_FAIL);
- } finally {
- LOG.info("锁被释放了");
- // 释放锁
- if (lock != null && lock.isHeldByCurrentThread()){
- lock.unlock();
- }
- }
- }
复制代码 到此这篇关于redis解决高并发看门狗策略的实现的文章就介绍到这了,更多相关redis 高并发看门狗策略内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!
来源:https://www.jb51.net/database/3360547u1.htm
免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作! |