利用Redis鎖解決高併發問題

2021-09-11 02:51:32 字數 2930 閱讀 9257

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

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

建立庫存表

create tablestorage(

idint(11) unsigned not null auto_increment,

numberint(11) default null,

primary key (id)

) engine=innodb auto_increment=1 default charset=latin1

設定初始庫存為10

建立訂單表

create tableorder(

idint(11) unsigned not null auto_increment,

numberint(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 false;}}

/*** @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 unsigned...

利用Redis鎖解決併發問題

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

Redis高併發問題

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