php使用redis锁限制并发访问类示例(学习记录)

在学习redis和mysql数据库锁机制的时候,经常让人头痛;
RedisLock.class.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
<!--?php /** * Redis锁操作类 * Date: 2016-06-30 * Author: fdipzone * Ver: 1.0 * * Func: * public lock 获取锁 * public unlock 释放锁 * private connect 连接 */ class RedisLock { // class start private $_config; private $_redis; /** * 初始化 * @param Array $config redis连接设定 */ public function __construct($config=array()){ $this-&gt;_config = $config;&lt;br ?--> $this-&gt;_redis = $this-&gt;connect();
}

/**
* 获取锁
* @param String $key 锁标识
* @param Int $expire 锁过期时间
* @return Boolean
*/

public function lock($key, $expire=5){
$is_lock = $this-&gt;_redis-&gt;setnx($key, time()+$expire);

// 不能获取锁
if(!$is_lock){

// 判断锁是否过期
$lock_time = $this-&gt;_redis-&gt;get($key);

// 锁已过期,删除锁,重新获取
if(time()&gt;$lock_time){
$this-&gt;unlock($key);
$is_lock = $this-&gt;_redis-&gt;setnx($key, time()+$expire);
}
}

return $is_lock? true : false;
}

/**
* 释放锁
* @param String $key 锁标识
* @return Boolean
*/

public function unlock($key){
return $this-&gt;_redis-&gt;del($key);
}

/**
* 创建redis连接
* @return Link
*/

private function connect(){
try{
$redis = new Redis();
$redis-&gt;connect($this-&gt;_config['host'],$this-&gt;_config['port'],$this-&gt;_config['timeout'],$this-&gt;_config['reserved'],$this-&gt;_config['retry_interval']);
if(empty($this-&gt;_config['auth'])){
$redis-&gt;auth($this-&gt;_config['auth']);
}
$redis-&gt;select($this-&gt;_config['index']);
}catch(RedisException $e){
throw new Exception($e-&gt;getMessage());
return false;
}
return $redis;
}

} // class end

?&gt;

demo.php

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
<!--?php require 'RedisLock.class.php'; $config = array( 'host' =&gt; 'localhost',&lt;br ?--> 'port' =&gt; 6379,
'index' =&gt; 0,
'auth' =&gt; '',
'timeout' =&gt; 1,
'reserved' =&gt; NULL,
'retry_interval' =&gt; 100,
);

// 创建redislock对象
$oRedisLock = new RedisLock($config);

// 定义锁标识
$key = 'mylock';

// 获取锁
$is_lock = $oRedisLock-&gt;lock($key, 10);

if($is_lock){
echo 'get lock success
'
;
echo 'do sth..
'
;
sleep(5);
echo 'success
'
;
$oRedisLock-&gt;unlock($key);

// 获取锁失败
}else{
echo 'request too frequently
'
;
}

?&gt;
1
2
3
4
5
6
7
8
9
10
11
测试方法:
打开两个不同的浏览器,同时在A,B中访问demo.php
如果先访问的会获取到锁
输出
get lock success
do sth..
success
另一个获取锁失败则会输出request too frequently
保证同一时间只有一个访问有效,有效限制并发访问。
为了避免系统突然出错导致死锁,所以在获取锁的时候增加一个过期时间,
如果已超过过期时间,即使是锁定状态都会释放锁,避免死锁导致的问题。
本文为 今天也想见到你 博客文章,转载无需和我联系,但请注明来自 今天也想见到你 博客 0925.wang

评论

  1. Windows Chrome 78.0.3904.108
    4年前
    2020-9-30 12:59:00

    666呀

    • 博主
      Windows Chrome 86.0.4238.2
      4年前
      2020-9-30 13:03:34

      是的呀

  2. 博主
    Windows Chrome 86.0.4238.2
    4年前
    2020-9-28 18:30:15

    测试评论

发送评论 编辑评论


				
|´・ω・)ノ
ヾ(≧∇≦*)ゝ
(☆ω☆)
(╯‵□′)╯︵┴─┴
 ̄﹃ ̄
(/ω\)
∠( ᐛ 」∠)_
(๑•̀ㅁ•́ฅ)
→_→
୧(๑•̀⌄•́๑)૭
٩(ˊᗜˋ*)و
(ノ°ο°)ノ
(´இ皿இ`)
⌇●﹏●⌇
(ฅ´ω`ฅ)
(╯°A°)╯︵○○○
φ( ̄∇ ̄o)
ヾ(´・ ・`。)ノ"
( ง ᵒ̌皿ᵒ̌)ง⁼³₌₃
(ó﹏ò。)
Σ(っ °Д °;)っ
( ,,´・ω・)ノ"(´っω・`。)
╮(╯▽╰)╭
o(*////▽////*)q
>﹏<
( ๑´•ω•) "(ㆆᴗㆆ)
😂
😀
😅
😊
🙂
🙃
😌
😍
😘
😜
😝
😏
😒
🙄
😳
😡
😔
😫
😱
😭
💩
👻
🙌
🖕
👍
👫
👬
👭
🌚
🌝
🙈
💊
😶
🙏
🍦
🍉
😣
Source: github.com/k4yt3x/flowerhd
颜文字
Emoji
小恐龙
花!
下一篇