redis鎖機制處理高併發

2021-10-05 01:53:53 字數 3000 閱讀 2540

這裡我們主要利用redis的setnx的命令來處理高併發。

setnx 有兩個引數。第乙個引數表示鍵。第二個引數表示值。如果當前鍵不存在,那麼會插入當前鍵,將第二個引數做為值。返回 1。如果當前鍵存在,那麼會返回0。

建立庫存表

create table `storage` (

`id` int(11) unsigned not null auto_increment,

`number` int(11) default null,

primary key (`id`)

) engine=innodb auto_increment=1 default charset=latin1

設定初始庫存為10

建立訂單表

create table `order` (

`id` int(11) unsigned not null auto_increment,

`number` int(11) default null,

primary key (`id`)

) engine=innodb auto_increment=1 default charset=latin1

測試不用鎖的時候

$pdo = new pdo('mysql:host=127.0.0.1;dbname=test', 'root', 'root');

$sql="select `number` from  storage where id=1 limit 1";

$res = $pdo->query($sql)->fetch();

$number = $res['number'];

if($number>0)

}

ab測試模擬併發,發現庫存是正確的。

mysql> select * from storage;

+----+--------+

| id | number |

+----+--------+

|  1 |      0 |

+----+--------+

1 row in set (0.00 sec)

在來看訂單表

mysql> select * from `order`;

+----+--------+

| id | number |

+----+--------+

|  1 |     10 |

|  2 |     10 |

|  3 |      9 |

|  4 |      7 |

|  5 |      6 |

|  6 |      5 |

|  7 |      5 |

|  8 |      5 |

|  9 |      4 |

| 10 |      1 |

+----+--------+

10 rows in set (0.00 sec)

發現存在幾個訂單都是操作的同乙個庫存資料,這樣就可能引起超賣的情況。

修改**加入redis鎖進行資料控制

<?php

/** * created by phpstorm.

* user: daisc

* date: 2018/7/23

* time: 14:45

*/class lock

public static function getinstance()

return self::$_instance = new  self();

}/**

* @function 加鎖

* @param $key 鎖名稱

* @param $exptime 過期時間

*/public function set($key,$exptime)

else

return  $this->_redis->setnx($key,time()+$exptime);}}

/*** @param $key 解鎖

*/public function del($key)

}$pdo = new pdo('mysql:host=127.0.0.1;dbname=test', 'root', 'root');

$lockobj = lock::getinstance();

//判斷是能加鎖成功

if($lock = $lockobj->set('storage',10))

}//解鎖

$lockobj->del('storage');

}else

再次進行ab測試,檢視測試結果

mysql> select * from `order`;

+----+--------+

| id | number |

+----+--------+

|  1 |     10 |

|  2 |      9 |

|  3 |      8 |

|  4 |      7 |

|  5 |      6 |

|  6 |      5 |

|  7 |      4 |

|  8 |      3 |

|  9 |      2 |

| 10 |      1 |

+----+--------+

10 rows in set (0.00 sec)

發現訂單表沒有操作同乙個庫存資料的情況。所以利用redis鎖是可以有效的處理高併發的。

這裡在加鎖的時候其實是可以不需要判斷過期時間的,這裡我們為了避免造成死鎖,所以加乙個過期時間的判斷。當過期的時候主動刪除該鎖。

Redis鎖機制處理高併發

文章正文 這裡我們主要利用redis的setnx的命令來處理高併發。setnx 有兩個引數。第乙個引數表示鍵。第二個引數表示值。如果當前鍵不存在,那麼會插入當前鍵,將第二個引數做為值。返回 1。如果當前鍵存在,那麼會返回0。建立庫存表 create table storage id int 11 u...

高併發Mysql樂觀鎖機制

為什麼80 的碼農都做不了架構師?高併發mysql樂觀鎖機使用舉例 以mysql innodb為例,使用version版本號方式 1,假設商品goods表中有乙個欄位status,status為1代表商品未被下單,status為2代表商品已經被下單,那麼我們對某個商品下單時必須確保該商品status...

Redis處理高併發機制原理及例項解析

1.redis是基於記憶體的,記憶體的讀寫速度非常快 2.redis是單執行緒的,省去了很多上下文切換執行緒的時間 3.redis使用多路復用技術,可以處理併發的連線。非阻塞io 內部實現採用epoll,採用了epoll 自己實現的簡單的事件框架。epoll中的讀 寫 關閉 連線都轉化成了事件,然後...