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