码迷,mamicode.com
首页 > 其他好文 > 详细

使用redis实现简单的锁机制

时间:2017-09-19 17:52:04      阅读:255      评论:0      收藏:0      [点我收藏+]

标签:数据   .com   utils   blog   setnx   就会   参数   失败   手册   

在测试第三方账号注册时,授权拉取后,如果两台手册同时点击注册按钮,数据库中就会新增两天一模一样的数据,而我们的需求是一个第三方账号只能绑定一个账号,所以,由此现象可以知道,这里产生了并发访问,我们应该通过加锁的形式来杜绝该现象的产生。那么,如何操作呢?

 我们先上代码:

<?php
/**
 * 加锁
 * @param string $action 业务逻辑,当前框架中未方法名即可
 * @param string $extra 额外参数,例如用户ID等
 * @return boolen true=加锁成功
 */
  function lock($key) {
    $Redis = new Redis();
    $Redis->connect(‘127.0.0.1‘, 6379) or die(‘redis连接失败‘);
if($Redis::setnx($key, 1)) { $Redis::expire($key, 30); //设置过期时间 return true; } //防止死锁,-1标识key存在,但未设置过期时间 if($Redis::ttl($key) == -1) { $Redis::expire($key, 5);//设置过期时间 } return false; }

由上述代码,我们可以分析得到:

1、先使用setnx设置key值,setnx的意思是:

  将 key 的值设为 value ,当且仅当 key 不存在。

  若给定的 key 已经存在,则 SETNX不做任何动作。

  SETNX 是『SET if Not eXists』(如果不存在,则 SET)的简写。

setnx不能设置过期时间,所以设置成功后应该调用expire来给key设置过期时间。

2、如果setnx设置失败了,则说明此时有别的用户加了锁,所以此时应该返回失败。

  但是如果之前的用户在获取锁时,即第一步setnx时成功了,但是redis宕机了,且也没有手动解锁,这就会造成下一个用户一直获取不到锁,这就被称为死锁。

  为了防止这种现象发生,我们可以调用redis的 ttl 方法:

    当 key 不存在时,返回 -2 。
    当 key 存在但没有设置剩余生存时间时,返回 -1 。
    否则,以秒为单位,返回 key 的剩余生存时间。
  所以,如果出现了死锁,即 ttl 返回值未 -1 的情况,我们应该为该key设置一个过期时间,给该用户一个缓冲时间,这里设置了5秒的缓冲时间。
 
以上就是加锁的简单完整机制。
 
参考手册:http://doc.redisfans.com/

使用redis实现简单的锁机制

标签:数据   .com   utils   blog   setnx   就会   参数   失败   手册   

原文地址:http://www.cnblogs.com/totian/p/7552646.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!