将该文件放到项目中(任意位置,能引入就行)
根据实际情况将文件中namespace和redis连接方式修改(该文件是以TP5为例)
```
~~~
<?php
namespace app\common\library;
class RedisLock {
private $_redis;
public function __construct() {
$this->_redis = $this->connect();
}
/**
* 获取锁
* @param String $lockName 锁标识
* @param Int $timeout 锁过期时间
* @return Boolean
*/
public function lock($lockName, $timeout=2){
$identifier=uniqid(); #获取唯一标识符,作为锁的值
$timeout=ceil($timeout); #确保是整数
while(true) #循环获取锁
{
if($this->_redis->setnx($lockName, $identifier)) #查看$lockName是否被上锁
{
$this->_redis->expire($lockName, $timeout); #为$lockName设置过期时间,防止死锁
return $identifier; #返回一维标识符
}
elseif ($this->_redis->ttl($lockName)===-1)
{
$this->_redis->expire($lockName, $timeout); #检测是否有设置过期时间,没有则加上(假设,客户端A上一步没能设置时间就进程奔溃了,客户端B就可检测出来,并设置时间)
}
usleep(0.01); #停止0.001ms
}
return false;
}
/**
* 释放锁
* @param String $lockName 锁标识
* @param String $identifier 锁值
* @return Boolean
*/
public function unlock($lockName,$identifier){
if($this->_redis->get($lockName)==$identifier) #判断是锁有没有被其他客户端修改
{
$this->_redis->multi();#开启事务
$this->_redis->del($lockName); #释放锁
$this->_redis->exec();#提交事务
return true;
}
else
{
return false; #其他客户端修改了锁,不能删除别人的锁
}
}
/**
* 创建redis连接
* @return Link
*/
private function connect(){
try{
$redis = new \Redis();
$redis->connect('127.0.0.1',6379);
//有密码时设置
// $redis->auth('');
}catch(Exception $e){
throw new Exception($e->getMessage());
return false;
}
return $redis;
}
}
~~~
```
调用
~~~
$lock = new RedisLock();
$lockName = 'snap_up_order';//锁名(自己随意写)
//获取锁
$identifier = $lock->lock($lockName);
if($identifier){
//拿到锁之后写自己的逻辑代码
//逻辑代码执行完后解锁
$lock->unlock($lockName, $identifier);
}
~~~