當一個業務執行時間超過自己設定的鎖釋放時間,那么會導致有其他線程進入,從而搶到同一個票,所有需要使用看門狗策略,其實就是開一個守護線程,讓守護線程去監控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();}}}