redis分布式锁实战

redis分布式锁
文章参考 https://www.cnblogs.com/linjiqin/p/8003838.html#!comments

1.获取锁
	采用这种方式的宗旨就是加锁和设置过期必须在一起 原子性
	使用jedis这个方法public String set(final String key, final String value, final String nxxx, final String expx,final long time)
	private static final String SET_IF_NOT_EXIST = "NX";//nxxx
	private static final String SET_WITH_EXPIRE_TIME = "PX";expx
	
	public static boolean incWorkOrderTryLock(String incidentCode, String requestId) {
		boolean flag = false;
		try {
			RedisService redisService = SpringContextUtil.getBean(RedisService.class);
			String str = redisService.setNx(BmConstant.INCWORKORDER_LOCK_PREFIX + incidentCode, requestId, BmConstant.INCWORKORDER_LOCK_EXPIRE_TIME);
			if("OK".equals(str)){
				flag = true;
			}
		} catch (Exception e) {
		   log.error("tryIncWorkOrderLock failed",e);
		}
		return flag;
	}
2.阻塞方式获取锁
	采用这种方式的宗旨就是加锁和设置过期必须在一起 原子性
	public static boolean incWorkOrderBlockLock(String incidentCode, String requestId, long blockTime){
		boolean flag = false;
		try {
			RedisService redisService = SpringContextUtil.getBean(RedisService.class);
			while (blockTime >= 0){
				String str = redisService.setNx(BmConstant.INCWORKORDER_LOCK_PREFIX + incidentCode, requestId, BmConstant.INCWORKORDER_LOCK_EXPIRE_TIME);
				if ("OK".equals(str)){
					flag = true;
					break;
				}
				Thread.sleep(BmConstant.INCWORKORDER_LOCK_SLEEP_TIME) ;
				blockTime -= BmConstant.INCWORKORDER_LOCK_SLEEP_TIME ;
			}
		} catch (Exception e) {
			log.error("blockIncWorkOrderLock failed",e);
		}
		return flag ;
	}
3.释放锁
	采用这种方式的宗旨就是 原子性
	public static boolean incWorkOrderUnLock(String incidentCode, String requestId){
		boolean flag = false;
		try {
			RedisService redisService = SpringContextUtil.getBean(RedisService.class);
			String script = "if redis.call('get', KEYS[1]) == ARGV[1] then return redis.call('del', KEYS[1]) else return 0 end";
			Object result = redisService.eval(script, Collections.singletonList(BmConstant.INCWORKORDER_LOCK_PREFIX + incidentCode),
					Collections.singletonList(requestId));
			if (1l == (long)result){
				flag = true;
			}
		} catch (Exception e) {
			log.error("unIncWorkOrderLock failed",e);
		}
		return flag;
	}
	
	错误示例
	public static void wrongReleaseLock2(Jedis jedis, String lockKey, String requestId) {
		// 判断加锁与解锁是不是同一个客户端
		if (requestId.equals(jedis.get(lockKey))) {
			// 若在此时,这把锁突然不是这个客户端的,则会误解锁
			jedis.del(lockKey);
		}
	}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值