php多程序模擬併發事務產生的問題小結

2022-10-06 17:45:15 字數 2151 閱讀 9777

前言

表drop table if exists `test程式設計客棧www.cppcns.com`;

create table if not exists `test` (

id int not null auto_increment ,

count int default 0 ,

primary key `id` (`id`)

) engine=innodb character set utf8mb4 collate = utf8mb4_bin comment '測試表';

insert into test (`count`) values (100);

php **

// 程序數量

$pro_count = 100;

$pids = ;

for ($i = 0; $i < $pro_count; ++$i)

else if ($pid > 0) else

$pdo->commit();

} catch(exception $e)

// 退出子程序

exit;

}}期望的結果

期望 count 字段減少的量超過 100,變成負數!也就是多減!

實際結果

併發 200 的情況下,執行多次後的結果分別如下:

1. count = 65

2. count = 75

3. count = 55

4. count = 84

...與期望結果相差甚遠!為什麼會出現這樣的現象呢?

解釋首先清楚下目前的程式執行環境,併發場景。何為併發,幾乎同時執行,稱之為併發。具體解釋如下:

程序 過程 獲取 更新

1-40 同時建立並執行 100 99

41-80 同時建立並執行 99 98

81 - 100 同時建立並執行 98 97

對上述第一行做解釋,第 1-40 個子程序的建立幾乎同時,執行也幾乎同時:

程序 1 獲取 count = 100,更新 99

程序 2 獲取 count = 100,更新 99

...程序 40 獲取 count = 100,更新 99

所以,實際上這些程序都做了一致的操作,並沒有按照預期的那樣:程序1 獲取 count=100,更新 99;程序 2 獲取程序1更新後的結果 count=99,更新98;...;程序 99 獲取程序 98更新後的結果count=1,更新0

,產生的現象就是少減了!!

結論採用上述做法實現的程式,庫存總是 >= 0。

疑問那要模擬超庫存的場景該如何設計程式呢?

仍然採用上述**,將以下**:

if ($count > 0)

修改成下面這樣:

if ($count > 0)

結果就會出現超庫存程式設計客棧!!

庫存 100,併發 200,最終庫存減少為 -63。為什麼會出現這樣的情況呢?以下描述了程式執行的具體過程

程序 1 獲取庫存 100,更新 99

程序 2 獲取庫存 100,更新 98(99 - 1)

程序 3 獲取庫存 100,更新 97(98 - 1)

....

程序 168 獲取庫存 1 ,更新 0(1-1)

程序 169 獲取庫存 1 ,更新 -1(0 - 1)

程序 170 獲取庫存 1 ,更新 -2(-1 - 1)

....

程序 200 獲取庫存 1,更新 -63(-62 - 1)

現在看來很懵逼,實際就是下面這條語句導致的:

$pdo->query('update test set `count` = `count` - 1 where id = 2');

這邊詳細闡述 程序 1,簡稱 a;程序 2,簡稱 b 他們具體的執行順序:

1. a 查詢到庫存 100

2. b 查詢到庫存 100

3. a 更新庫存為 99(100 - 1),這個應該秒懂

4. b 更新庫存為 98(99 - 1)

- b 在執行更新操作的時候拿到的是 a 更新後的庫存!

- 為什麼會這樣?因為更新語句是 `update test set count = count - 1 where id = 2`

總結本文標題: php多程序模擬併發事務產生的問題小結

本文位址:

PHP的多程序

一般有兩種方法,一種是使用php自帶的pcntl 函式 僅限linux 另一種就是使用popen proc open,然後在php內部控制程序數量。php提供了一系列的pcntl 函式,顧名思義就是process control functions,專門用來管理程序的。最常用的就是pcntl for...

PHP的多程序

一般有兩種方法,一種是使用php自帶的pcntl 函式 僅限linux 另一種就是使用popen proc open,然後在php內部控制程序數量。php提供了一系列的pcntl 函式,顧名思義就是process control functions,專門用來管理程序的。最常用的就是pcntl for...

PHP多程序併發控制的測試用例

轉http blog.s135.com post 311 最近遇到乙個問題,linux下的php命令列程式作為守護程序,需要從佇列檔案中讀一行資料,通過tcp協議傳送給外地的接收伺服器,再讀下一行資料,再傳送。當本地與外地的網路狀況不好時,有時候傳送一條資料所耗費的時間就較長,累積起來容易造成佇列堵...