关于redis 锁(分布式锁)的问题

来源:互联网 发布:压缩空气管道计算软件 编辑:程序博客网 时间:2024/05/21 13:54

首先,工作中的redis是从阿里获取的资源,工作需求有抢红包和签到的功能需求,这时就难免出现并发,因而涉及到锁的问题,网上搜了搜相关知识

不少是用setnx和getset实现,例如:http://blog.csdn.net/ugg/article/details/41894947 等等,个人认为考虑非常全面,但是感觉比较复杂,个人认为

可以通过redis incr命令来实现该功能,本人菜鸟,如果不妥,还望不吝赐教


具体逻辑:给一个key加锁,通过incr命令,当个数为1的时候说明有线程获得锁,因而只要判断是否大于1可以知道是否有人获取锁,再设置一个过期

时间,该期间内不断的循环请求,获取锁则获取,否则视为超时(超时处理比较粗糙,直接视为死锁超时或者 返回失败提示)


具体代码(java):

  long TIME_LIMIT = 3000;

  long getLockTime = 0;

  while(jedis.incr(lockKey) > 1 && getLockTime < TIME_LIMIT){

  // 等待时长为随机的,最少为50毫秒左右,等待时长长短看人品

  long curWatiTime = 50 + Math.round(250 * Math.random());
getLockTime += curWatiTime;
Thread.sleep(curWatiTime);

 }

//防止程序中途遇到未知的问题,此时设置一个过期时间

jedis.expire(lockKey,1000);

//判断当获取锁的时间超过时间限制了,抛出异常(严谨起见)

  if(getLockTime > TIME_LIMIT){

   throw new Exception("get Lock failed , lockKey "+ lockKey +" locked");

  }


关键代码如上所示,获取锁的service调用该段代码的方法,当处理完自己的业务后,在finally模块删除该key

释放该锁


具体设计看具体情况,如何使逻辑更加严谨,以及如何处理各种异常,如何给客户端更为妥当的提示都是要考虑的


看过 setnx getset 实行redis锁的相关文档

http://blog.csdn.net/ugg/article/details/41894947










原创粉丝点击