PHP使用Redis实现防止大并发下二次写入的方法

yipeiwu_com6年前PHP代码库

本文实例讲述了PHP使用Redis实现防止大并发下二次写入的方法。分享给大家供大家参考,具体如下:

PHP调用redis进行读写操作,大并发下会出现:读取key1,没有内容则写入内容,但是大并发下会出现同时多个php进程写入的情况,这个时候需要加一个锁,即获取锁的php进程有权限写。

$lock_key = 'LOCK_PREFIX' . $redis_key;
$is_lock = $redis->setnx($lock_key, 1); // 加锁
if($is_lock == true){ // 获取锁权限
  $redis->setex($redis_key, $expire, $data); // 写入内容
  // 释放锁
  $redis->del($lock_key);
}else{
  return true; // 获取不到锁权限,直接返回
}

思路是:设置一个锁的key,setnx是原子操作,只能一个进程写入成功,写入成功返回true(表示获取锁权限),然后写入内容再释放锁即删除锁key。获取不到锁的进程直接返回。但是这里有种情况,获取锁权限的进程,获取锁后运行报错了,导致没有释放锁,那么一直就不能写入内容,这时就需要拿不到锁权限的进程去判断锁的剩余有效时间,如果为-1则设置锁的有效时间为5秒(预留5秒给拿到锁的进程的运行时间,足够多了)。改良后的代码:

$lock_key = 'LOCK_PREFIX' . $redis_key;
$is_lock = $redis->setnx($lock_key, 1); // 加锁
if($is_lock == true){ // 获取锁权限
  $redis->setex($redis_key, $expire, $data); // 写入内容
  // 释放锁
  $redis->del($lock_key);
}else{
  // 防止死锁
  if($redis->ttl($lock_key) == -1){
    $redis->expire($lock_key, 5);
  }
  return true; // 获取不到锁权限,直接返回
}

更多关于PHP相关内容感兴趣的读者可查看本站专题:《php+redis数据库程序设计技巧总结》、《php面向对象程序设计入门教程》、《PHP基本语法入门教程》、《PHP数组(Array)操作技巧大全》、《php字符串(string)用法总结》、《php+mysql数据库操作入门教程》及《php常见数据库操作技巧汇总

希望本文所述对大家PHP程序设计有所帮助。

相关文章

JavaScript实现滚动栏效果的方法

本文实例讲述了JavaScript实现滚动栏效果的方法。分享给大家供大家参考。具体如下: <!DOCTYPE html> <html> <head...

浅谈web上存漏洞及原理分析、防范方法(文件名检测漏洞)

我们通过前篇:<浅谈web上存漏洞及原理分析、防范方法(安全文件上存方法)>,已经知道后端获取服务器变量,很多来自客户端传入的。跟普通的get,post没有什么不同。下面我们...

无刷新动态加载数据 滚动条加载适合评论等页面

无刷新动态加载数据 滚动条加载适合评论等页面

滚屏加载更多数据,适合评论等页面 本例的数据库很简单,一看就明了  复制代码 代码如下: <div id="container"> <?php $query=...

php实现的常见排序算法汇总

本文汇总了常见的php排序算法,在进行算法设计的时候有不错的借鉴价值。现分享给大家供参考之用。具体如下: 一、插入排序 用文字简单的描述,比如说$arr = array(4,2,4,6,...

php防止sql注入简单分析

本文实例分析了php防止sql注入简单方法。分享给大家供大家参考。具体如下: 这里只说一个简单的方法 防止Sql注入的方法有很多,这里要说的其实就是漏洞演练平台Dvwa里的一种方式 直接...