PHP+Lua脚本实现分布式锁

直接上代码

<?php
$redis=new Redis();
$redis->connect("127.0.0.1",6379);
$redis->select(0);


//PHP中使用redis拓展执行脚本时,eval方法的参数 3个,第一个是脚本代码,
//第二个是一个数组,参数数组,第三个参数是个整数,
//表示第二个参数中的前几个是key参数,剩下的都是附加参数
//传入1个key 2个线程的唯一标识id  分布式锁的失效时间
$lua =getLuaLock();

$res=$redis->eval($lua,['lock','thread-002','15'],1);
if($res){
	echo "获取到分布式锁...\n";
	echo "开始进行业务\n";
	$Num=0;
	while($Num<10){
		sleep(1);
		$Num++;
		echo $Num."\n";
	}
	echo "业务结束\n";
	$unlock=getunLockLua();
	$redis->eval($unlock,['lock','thread-002','15'],1);
	echo "释放分布式锁\n";
}
$redis->close();//关闭redis

/**
 *获取分布式锁脚本
 *@param key 分布式锁的key名称
 *@param threadId 当前线程的id
 *@param expireTime 分布式锁失效时间
 **/
function getLuaLock(){
	$lua= <<<EOF
   local  key=KEYS[1];
  local threadId=ARGV[1];
  local expireTime=ARGV[2];
    if (redis.call('exists',key)==0) then
      redis.call('hset',key,threadId,'1');
      redis.call('expire',key,threadId,expireTime);
      return 1;
   end;
  if (redis.call('hexists',key,threadId) ==1) then
        redis.call('hincrby',key,threadId,'1');
        redis.call('expire',key,expireTime);
        return 1;
  end;
  return 0;
EOF;
 return $lua;
}
/**
 *释放分布式Lua脚本
 *@param key 分布式锁的key名称
 *@param threadId 当前线程的id
 *@param expireTime 分布式锁失效时间
 */
function getunLockLua(){
	$lua= <<<EOF
   local  key=KEYS[1];
  local threadId=ARGV[1];
  local expireTime=ARGV[2];
  if(redis.call('HEXISTS',key,threadId)==0) then
      return nil;
   end;
  local count=redis.call('HINCRY',key,threadId,-1);
  if(count>0) then
        redis.call('EXPIRE',key,expireTime);
      return nil;
  else
       redis.call('DEL',key);
       return nil;
  end;
EOF;
 return $lua;

}

运行效果

在这里插入图片描述

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值