php多進(jìn)程模擬并發(fā)事務(wù)產(chǎn)生的問(wèn)題小結(jié)_第1頁(yè)
php多進(jìn)程模擬并發(fā)事務(wù)產(chǎn)生的問(wèn)題小結(jié)_第2頁(yè)
php多進(jìn)程模擬并發(fā)事務(wù)產(chǎn)生的問(wèn)題小結(jié)_第3頁(yè)
php多進(jìn)程模擬并發(fā)事務(wù)產(chǎn)生的問(wèn)題小結(jié)_第4頁(yè)
php多進(jìn)程模擬并發(fā)事務(wù)產(chǎn)生的問(wèn)題小結(jié)_第5頁(yè)
已閱讀5頁(yè),還剩1頁(yè)未讀, 繼續(xù)免費(fèi)閱讀

下載本文檔

版權(quán)說(shuō)明:本文檔由用戶(hù)提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請(qǐng)進(jìn)行舉報(bào)或認(rèn)領(lǐng)

文檔簡(jiǎn)介

第php多進(jìn)程模擬并發(fā)事務(wù)產(chǎn)生的問(wèn)題小結(jié)前言

本文通過(guò)實(shí)例代碼給大家介紹了關(guān)于php多進(jìn)程模擬并發(fā)事務(wù)產(chǎn)生的一些問(wèn)題,分享出來(lái)供大家參考學(xué)習(xí),下面話不多說(shuō)了,來(lái)一起看看詳細(xì)的介紹吧

droptableifexists`test`;

createtableifnotexists`test`(

idintnotnullauto_increment,

countintdefault0,

primarykey`id`(`id`)

)engine=innodbcharactersetutf8mb4collate=utf8mb4_bincomment'測(cè)試表';

insertintotest(`count`)values(100);

php代碼

//進(jìn)程數(shù)量

$pro_count=100;

$pids=[];

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

$pid=pcntl_fork();

if($pid0){

//主進(jìn)程

thrownewException('創(chuàng)建子進(jìn)程失敗:'.$i);

}elseif($pid0){

//主進(jìn)程

$pids[]=$pid;

}else{

//子進(jìn)程

try{

$pdo=newPDO(...);

$pdo-beginTransaction();

$stmt=$pdo-query('select`count`fromtest');

$count=$stmt-fetch(PDO::FETCH_ASSOC)['count'];

$count=intval($count);

if($count0){

$count--;

$pdo-query('updatetestset`count`='.$count.'whereid=2');

$pdo-commit();

}catch(Exception$e){

$pdo-rollBack();

throw$e;

//退出子進(jìn)程

exit;

}

期望的結(jié)果

期望count字段減少的量超過(guò)100,變成負(fù)數(shù)!也就是多減!

實(shí)際結(jié)果

并發(fā)200的情況下,運(yùn)行多次后的結(jié)果分別如下:

1.count=65

2.count=75

3.count=55

4.count=84

...

與期望結(jié)果相差甚遠(yuǎn)!為什么會(huì)出現(xiàn)這樣的現(xiàn)象呢?

解釋

首先清楚下目前的程序運(yùn)行環(huán)境,并發(fā)場(chǎng)景。何為并發(fā),幾乎同時(shí)執(zhí)行,稱(chēng)之為并發(fā)。具體解釋如下:

進(jìn)程過(guò)程獲取更新

1-40同時(shí)創(chuàng)建并運(yùn)行10099

41-80同時(shí)創(chuàng)建并運(yùn)行9998

81-100同時(shí)創(chuàng)建并運(yùn)行9897

對(duì)上述第一行做解釋?zhuān)?-40個(gè)子進(jìn)程的創(chuàng)建幾乎同時(shí),運(yùn)行也幾乎同時(shí):

進(jìn)程1獲取count=100,更新99

進(jìn)程2獲取count=100,更新99

...

進(jìn)程40獲取count=100,更新99

所以,實(shí)際上這些進(jìn)程都做了一致的操作,并沒(méi)有按照預(yù)期的那樣:進(jìn)程1獲取count=100,更新99;進(jìn)程2獲取進(jìn)程1更新后的結(jié)果count=99,更新98;...;進(jìn)程99獲取進(jìn)程98更新后的結(jié)果count=1,更新0

,產(chǎn)生的現(xiàn)象就是少減了!!

結(jié)論

采用上述做法實(shí)現(xiàn)的程序,庫(kù)存總是=0。

疑問(wèn)

那要模擬超庫(kù)存的場(chǎng)景該如何設(shè)計(jì)程序呢?

仍然采用上述代碼,將以下代碼:

if($count0){

$count--;

$pdo-query('updatetestset`count`='.$count.'whereid=2');

}

修改成下面這樣:

if($count0){

$pdo-query('updatetestset`count`=`count`-1whereid=2');

}

結(jié)果就會(huì)出現(xiàn)超庫(kù)存??!

庫(kù)存100,并發(fā)200,最終庫(kù)存減少為-63。為什么會(huì)出現(xiàn)這樣的情況呢?以下描述了程序運(yùn)行的具體過(guò)程

進(jìn)程1獲取庫(kù)存100,更新99

進(jìn)程2獲取庫(kù)存100,更新98(99-1)

進(jìn)程3獲取庫(kù)存100,更新97(98-1)

....

進(jìn)程168獲取庫(kù)存1,更新0(1-1)

進(jìn)程169獲取庫(kù)存1,更新-1(0-1)

進(jìn)程170獲取庫(kù)存1,更新-2(-1-1)

....

進(jìn)程200獲取庫(kù)存1,更新-63(-62-1)

現(xiàn)在看來(lái)很懵逼,實(shí)際就是下面這條語(yǔ)句導(dǎo)致的:

$pdo-query('updatetestset`count`=`count`-1whereid=2');

這邊詳細(xì)闡述進(jìn)程1,簡(jiǎn)稱(chēng)a;進(jìn)程2,簡(jiǎn)稱(chēng)b他們具體的執(zhí)行順序:

1.a查詢(xún)到庫(kù)存100

2.b查詢(xún)到庫(kù)存100

3.a更新庫(kù)存為99(100-1),這個(gè)應(yīng)該秒懂

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

-b在執(zhí)行更新操作的時(shí)候拿到的是a更新后的庫(kù)存!

-為什么會(huì)這

溫馨提示

  • 1. 本站所有資源如無(wú)特殊說(shuō)明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請(qǐng)下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請(qǐng)聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶(hù)所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁(yè)內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒(méi)有圖紙預(yù)覽就沒(méi)有圖紙。
  • 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
  • 5. 人人文庫(kù)網(wǎng)僅提供信息存儲(chǔ)空間,僅對(duì)用戶(hù)上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對(duì)用戶(hù)上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對(duì)任何下載內(nèi)容負(fù)責(zé)。
  • 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請(qǐng)與我們聯(lián)系,我們立即糾正。
  • 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶(hù)因使用這些下載資源對(duì)自己和他人造成任何形式的傷害或損失。

評(píng)論

0/150

提交評(píng)論