實現redis分散式鎖
阿新 • • 發佈:2021-01-08
因專案需要,需要對快取中資料進行頻繁的讀寫操作,為了防止併發寫覆蓋問題,在程式中加了redis實現的分散式鎖來控制併發寫的場景。
先上程式碼,後期更新。
/** * 更新充值碼中已使用次數 * * @param request */ private void updateRechargeCodeCache(RechargeByCodeRequest request) { // 最大重試次數 int retryTimes = 10; // 獲取充值碼資訊 String lockKey = "recharge_card_" + request.getChannel() + "_" + request.getRechargeCode() + "_lock"; String rechargeCodeKey = "recharge_card_" + request.getChannel() + "_" + request.getRechargeCode(); LoggerUtils.logBizInfo("updateRechargeCodeCache,lockKey:" + lockKey + "rechargeCodeKey:" + rechargeCodeKey); try { for (int i=0; i<retryTimes; i++) { // 獲取分散式鎖 if (marketCacheService.setnx(lockKey, "1", 1L, TimeUnit.SECONDS)) { LoggerUtils.logBizInfo("updateRechargeCodeCache,lockKey:" + lockKey + ",加鎖成功"); String rechargeCodeValue = marketCacheService.get(rechargeCodeKey); LoggerUtils.logBizInfo("updateRechargeCodeCache,更新前:" + rechargeCodeValue); if (StringUtils.isEmpty(rechargeCodeValue)) { throw new MarketApplicationException(MktResultCodeEnum.SCAN_CODE_INVALID); } RechargeCodeModel rechargeCodeModel = BaseDto.fromJson(rechargeCodeValue, new TypeReference<RechargeCodeModel>() {}); // 更新充值碼使用次數 rechargeCodeModel.setUsedTimes(rechargeCodeModel.getUsedTimes() + 1); marketCacheService.set(rechargeCodeKey, rechargeCodeModel.toString(), 60L, TimeUnit.DAYS); LoggerUtils.logBizInfo("updateRechargeCodeCache,更新後:" + marketCacheService.get(rechargeCodeKey)); // 刪除分散式鎖 marketCacheService.delete(lockKey); LoggerUtils.logBizInfo("updateRechargeCodeCache,lockKey:" + lockKey + ",刪除鎖成功"); break; } else { LoggerUtils.logBizInfo("updateRechargeCodeCache,lockKey:" + lockKey + ",加鎖失敗,重試次數:" + i); // 休眠10毫秒後重試 Thread.sleep(10L); } } } catch (Exception e) { LoggerUtils.logBizError("更新充值碼中已使用次數失敗:" + e); } }