這裡我們主要利用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中的讀 寫 關閉 連線都轉化成了事件,然後...