实现redis分布式锁

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

  

原文地址:https://www.cnblogs.com/atai/p/14248544.html