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

我们先上代码:

<?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实现简单的锁机制的更多相关文章

  1. 基于Redis的简单分布式锁的原理

    参考资料:https://redis.io/commands/setnx 加锁是为了解决多线程的资源共享问题.Java中,单机环境的锁可以用synchronized和Lock,其他语言也都应该有自己的 ...

  2. 使用Redis模拟简单分布式锁,解决单点故障的问题

    需求描述: 最近做一个项目,项目中有一个功能,每天定时(凌晨1点)从数据库中获取需要爬虫的URL,并发送到对应的队列中,然后客户端监听对应的队列,然后执行任务.如果同时部署多个定时任务节点的话,每个节 ...

  3. php+redis 学习 三 乐观锁

    <?php header('content-type:text/html;chaeset=utf-8'); /** * redis实战 * * 实现乐观锁机制 * * @example php ...

  4. php+redis 学习 二 悲观锁

    <?php header('content-type:text/html;chaeset=utf-8'); /** * redis实战 * * 实现悲观锁机制 * */ $timeout = 5 ...

  5. 【Redis 分布式锁】(1)一把简单的“锁”

    原文链接:https://www.changxuan.top/?p=1230 在单体架构向分布式集群架构演进的过程中,项目中必不可少的一个功能组件就是分布式锁.在开发团队有技术积累的情况下,做为团队的 ...

  6. Redis 利用锁机制来防止缓存过期产生的惊群现象-转载自 http://my.oschina.net/u/1156660/blog/360552

    首先,所谓的缓存过期引起的“惊群”现象是指,在大并发情况下,我们通常会用缓存来给数据库分压,但是会有这么一种情况发生,那就是在一定时间 内生成大量的缓存,然后当缓存到期之后又有大量的缓存失效,导致后端 ...

  7. Redis Cluster架构和设计机制简单介绍

    之前另一篇文章也介绍了 Redis Cluster (link,在文章的后半部分) 今天看到这一篇,简单说一下(http://hot66hot.iteye.com/blog/2050676) 作者的目 ...

  8. redis锁机制介绍与实例

    转自:https://m.jb51.net/article/154421.htm 今天小编就为大家分享一篇关于redis锁机制介绍与实例,小编觉得内容挺不错的,现在分享给大家,具有很好的参考价值,需要 ...

  9. Mysql锁机制简单了解一下

    历史文章推荐: 可能是最漂亮的Spring事务管理详解 面试中关于Java虚拟机(jvm)的问题看这篇就够了 Java NIO 概览 关于分布式计算的一些概念 一 锁分类(按照锁的粒度分类) Mysq ...

随机推荐

  1. Spring Cloud 入门 Consul-Client服务提供

    前面介绍了 Rureka Client服务提供, 只需要改pom.xml部分内容 1.pom.xml <?xml version="1.0" encoding="U ...

  2. docker基础——关于安装、常用指令以及镜像制作初体验

    为什么使用docker docker就是一个轻量级的虚拟机,他解决的是服务迁移部署的时候环境配置问题.比如常见的web服务依赖于jdk.Tomcat.数据库等工具,迁移项目就需要在新的机器重新配置这些 ...

  3. Ansible工作架构和原理

    特性 模块块化调用持定的模块,完成持定任务 有Paramiko,PyYAML,Jinja2(模板语言)三个关键模块 支持自定义模块 基于Python语法头现 部署简单,基于python和SSH(默认已 ...

  4. lvs+ipvsadm负载均衡

    使用LVS实现负载均衡原理及安装配置详解 负载均衡集群是 load balance 集群的简写,翻译成中文就是负载均衡集群.常用的负载均衡开源软件有nginx.lvs.haproxy,商业的硬件负载均 ...

  5. Linux中的代码编辑器vim

    Vim的三种工作模式 命令行模式 插入模式 底行模式 Vim 的命令行模式 命令行模式是进入vim后的初始模式,在该模式下主要是使用方向键来移动光标的位置,并通过相应的命令来进行文字的编辑. 切换方法 ...

  6. django-simple-captcha

    在注册页面生成验证码的时候,出现错误如下: build_attrs() takes from 1 to 2 positional arguments but 3 were given, 不知道为什么报 ...

  7. JS 金钱格式化

    JavaScript Money Format(用prototype对Number进行扩展) Number.prototype.formatMoney = function (places, symb ...

  8. Mac 小技巧

    本文的大部分技巧来自于池建强老师的<MacTalk.人生元编程>,感谢他的辛苦付出,本文多系整理而已. 终端输入说英语 说英语时我们当然希望有标准发音.在Mac中不需要字典,直接在终端里输 ...

  9. SSTI注入绕过(沙盒逃逸原理一样)

    在python沙盒逃逸中绕过道理是一样的. 1.python沙盒中删除了很多模块,但是没有删除reload reload(__builtins__),重新加载被删除的模块,直接命令执行,只用于py2 ...

  10. SQLite3中dos命令下退出"...>"状态的方法

    今天在看Android中SQLite,跟着书上一步一步走,在dos中敲命令时候不小心敲错了,命令行就会突然变成”…>”这样的,本来是”sqlite>”的,然后接下来后面的就没办法在继续操作 ...