因项目需要,需要对缓存中数据进行频繁的读写操作,为了防止并发写覆盖问题,在程序中加了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); } }