利用Redis鎖解決高併發問題

2022-06-20 07:36:11 字數 3213 閱讀 3758

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

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 tablestorage idint 11 unsigned...

利用Redis鎖解決併發問題

用redis處理高併發是個很常見的方式,因為redis的訪問效率很高 直接訪問記憶體 一般我們會用來處理 一瞬間的併發量。那如果要使用redis來進行高併發問題的解決的話,應注意以下幾點 1 首先我們要先知道,我們在儲存時,應使用redis的setnx方法,不應該使用set方法,因為setnx擁有原...

Redis高併發問題

商品搶購秒殺等活動 使用redis列表結構實現佇列資料結構,強拆的用rpush入隊,再用lpop出隊.redis宕機或者連線不上 解決方法 配置主從複製,配置哨兵模式,一旦發現主機宕機,讓下乙個從機當做主機。最壞的情況,只能關閉redis連線,去往資料庫連線。但由於資料量大,這樣sql資料庫也會宕掉...