最新消息:欢迎加入小松的QQ群一起讨论一起学习,服务器快到期了,新买了台服务器,最近要做服务器迁移

php版redis锁

PHP 155浏览 0评论

根据《redis 实战》书讲的redis锁的章节python修改成的php代码

为什么不用watchmultiexec事务主要还是效率问题,要结合前面的章节具体分析一下

<?php
$redis = new \Redis();

if ($redis->connect('127.0.0.1','6379') == false) {
    die($redis->getLastError());
}
item_lock($redis);
//redis 锁
function item_lock($redis){
    $locked=acquire_lock($redis,'market');
    if($locked==false){
        return false;
    }
    try{
        if($redis->Llen("success")>=10){
            return false;
        }
        $redis->LPUSH("success",rand(1,20));
    }finally  {//不管try代码是否错误都执行release_lock 解锁
        release_lock($redis, 'market', $locked);
    }
}
/**
 * [release_lock 释放锁]
 * @Author   admin@phpsong.com
 * @DateTime 2016-12-01T14:55:36+0800
 * @param    [type]                   $redis      [description]
 * @param    [type]                   $lockname   [description]
 * @param    [type]                   $identifier [description]
 * @return   [type]                               [description]
 */
function release_lock($redis, $lockname, $identifier){
    $lokename = 'lock:'.$lockname;
    while (true) {
        try{
            $redis->watch($lokename);
            if($redis->get($lockname) == $identifier){
                $redis->multi();
                $redis->delete($lockname);
                $redis->exec();
                return true;
            }
            $redis->unwatch();
            break;
        }catch(Exception $e) {
            //release_lock($redis, $lockname, $identifier);
            //echo 'Message: ' .$e->getMessage();
        }

    }

    return false;
}
/**
 * [redis加锁]
 * @Author   qiuyisong@dodoca.com
 * @DateTime 2016-12-01T14:23:53+0800
 * @param    [type]                   $redis           [redis 对象]
 * @param    [type]                   $lokename        [锁的民族]
 * @param    integer                  $acquire_timeout [锁超时时间]
 * @return   [type]                                    [description]
 */
function acquire_lock($redis, $lockname, $acquire_timeout=10, $lock_timeout=10){
    $identifier = uuid();
    $end = time()+$acquire_timeout;
    $lockname ='lock:'.$lockname;
    while(time()<$end){
        if($redis->setnx($lockname,$identifier)){//命令在指定的 key 不存在时,为 key 设置指定的值。
            $redis->expireat($lockname, $lock_timeout);
            return $identifier;
        }elseif($redis->ttl($lockname)==-1){//命令以秒为单位返回 key 的剩余过期时间
            $redis->expireat($lockname, $lock_timeout);
        }
        sleep(0.001);
    }
    return false;
}
/**
 * [uuid 生成uuid]
 * @Author   admin@phpsong.com
 * @DateTime 2016-12-01T14:32:09+0800
 * @return   [type]                   [description]
 */
function  uuid()    
{    
    $chars = md5(uniqid(mt_rand(), true));    
    $uuid = substr ( $chars, 0, 8 ) . '-'  
            . substr ( $chars, 8, 4 ) . '-'   
            . substr ( $chars, 12, 4 ) . '-'  
            . substr ( $chars, 16, 4 ) . '-'  
            . substr ( $chars, 20, 12 );    
    return $uuid ;    
}  

exit;
QQ交流群:136351212

如无特别说明,本站文章皆为原创,若要转载,务必请注明以下原文信息:
转载保留版权:小松博客» php版redis锁
本文链接地址:https://www.phpsong.com/2910.html

发表我的评论
取消评论
表情

Hi,您需要填写昵称和邮箱!

  • 昵称 (必填)
  • 邮箱 (必填)
  • 网址
木有头像就木有JJ!点这里按步骤申请Gravatar头像吧!