redis分布式锁

redis 实现分布式锁

 高并发下回出现数据错乱  如何解决 
 
 1 使用 redis 的setnx 
 Redis Setnx(SET if Not eXists) 命令在指定的 key 不存在时,为 key 设置指定的值

 $goods_id = 1;
 $exists redis->setnx(goods_id,"value");
 if(!$exits){
  return false; // 如果上面设置redis成功 说明是第一次进来,否则就是第二次 第三次,进来 直接返回false

 }
 // 执行逻辑


 2 上面的问题 没有释放锁,那么这个商品,就永远没有其他人可以操作了。
 解决办法 执行完成后释放锁

 
 try{
 $exists redis->setnx(goods_id,"value");
 if(!$exits){
  return false; // 如果上面设置redis成功 说明是第一次进来,否则就是第二次 第三次,进来 直接返回false

 }

 // 执行逻辑


 }finally{

 	$redis->delete(key);
 }

 3. 上面程序问题,加入执行到finally之前,程序挂掉了,那锁还是永久没有被释放 
 解决办法 设置redis的时候,设置超时时间 并且是原子的 设置值和超时时间一起设置 

 4.上面程序问题 加入我程序还没执行完成,redis锁设置的超时时间到了
 外面等着一堆请求进来,这个时候,当前请求执行完成,我的锁已经自动过期了,我然后把刚刚进来的锁给释放了
 相当于释放了别人的锁。这样也许这把锁就永久都用不上,我放了别人的锁,第三个又进来,第二个又放了
 第三个的锁

 解决办法 只能释放自己的锁 
 redis设置值得时候,弄一个唯一值作为键值 这样就不会释放到别人的锁了

$value = md5(microtime();
 $redis->setnx($key,$value,10);

 finally{
   $value = $redis->get($key)
   if($value == $value){
     $redis->delete();
   }

 }


5 .上面程序还有问题 如何控制我在程序还没有执行完的时候,redis锁不因为redis ttl自动过期

 思路 可以启动定时器,在上面过期时间三分之一的时候,补齐时间,比如十秒自动过期 ,
 定时器检测,当本程序还没执行完,而且到了三秒了,补齐为10s 



java有个现成的 Redisson
php https://github.com/ronnylt/redlock-php

  

b站视频学习地址 https://www.bilibili.com/video/BV1d4411y79Y?p=1

原文地址:https://www.cnblogs.com/brady-wang/p/13388286.html