php如何解决并发问题,PHP如何解决并发问题
PHP如何解決并發問題
有個問題:
一個進程開啟事務對表的某一行做了修改,但還沒有提交,另一個進程查詢該行數據,獲取到的是原始的,這時候上面的事物提交了,我再用這個原始數據的時候就有問題……
那我們該怎么解決這個問題呢?
1、文件鎖
如果對該表的更新或插入只有一個文件,這種方式是可以解決的
實現方式如下:
public static functioncbInventoryReserve() {$LOCK_FILE_PATH = $_SERVER[‘DOCUMENT_ROOT‘]."wmsinventoryapi/inventory/InventoryReserve.php";$fp = fopen( $LOCK_FILE_PATH, "r");if (!$fp) {die("Failed to open the lock file!");
}flock ( $fp,LOCK_EX );//需要進行的操作
$params = Flight::request()->getBody();$params = json_decode($params, true);if (! is_array($params) || empty($params)) {
Flight::sendRouteResult(array("error_code" => "40002","error_info" => "params empty"));
}$result = \Inventory\InventoryEngine::getInstance()->inventoryReserve($params);flock ( $fp,LOCK_UN );fclose ( $fp);
Flight::sendRouteResult($result);
}
函數說明??flock()會依參數operation所指定的方式對參數fd所指的文件做各種鎖定或解除鎖定的動作。此函數只能鎖定整個文件,無法鎖定文件的某一區域。
參數??operation有下列四種情況:
LOCK_SH 建立共享鎖定。多個進程可同時對同一個文件作共享鎖定。
LOCK_EX 建立互斥鎖定。一個文件同時只有一個互斥鎖定。
LOCK_UN 解除文件鎖定狀態。
LOCK_NB 無法建立鎖定時,此操作可不被阻斷,馬上返回進程。通常與LOCK_SH或LOCK_EX 做OR(|)組合。
單一文件無法同時建立共享鎖定和互斥鎖定,而當使用dup()或fork()時文件描述詞不會繼承此種鎖定。
返回值??返回0表示成功,若有錯誤則返回-1,錯誤代碼存于errno。
換言之:
使用共享鎖LOCK_SH,如果是讀取,不需要等待,但如果是寫入,需要等待讀取完成。
使用獨占鎖LOCK_EX,無論寫入/讀取都需要等待。
LOCK_UN,無論使用共享/讀占鎖,使用完后需要解鎖。
LOCK_NB,當被鎖定時,不阻塞,而是提示鎖定。
為了更好的移植性,對于文件的打開與關閉我選擇了fopen和fclose的組合,但flock的第一個參數要求的是int類型的文件描述符。這里對fopen返回的FILE類型的文件指針進行轉換,轉換為int型的文件描述符 (假設open函數返回的文件描述符為fd,而fopen返回的文件指針為*fp,則fd等價于fp->_fileno).
2、序列化接口(對象序列化)
所有php里面的值都可以使用函數serialize()來返回一個包含字節流的字符串來表示。unserialize()函數能夠重新把字符串變回php原來的值。 序列化一個對象將會保存對象的所有變量,但是不會保存對象的方法,只會保存類的名字。
classA {public $one = 1;public functionshow_one() {echo $this->one;
}
}//page1.php:
include("classa.inc");$a = newA;$s = serialize($a);//把變量$s保存起來以便文件page2.php能夠讀到
file_put_contents(‘store‘, $s);//page2.php:
// 要正確了解序列化,必須包含下面一個文件
include("classa.inc");$s = file_get_contents(‘store‘);$a = unserialize($s);//現在可以使用對象$a里面的函數 show_one()
$a->show_one();?>
3、select *** for update
Select …forupdate語句是我們經常使用手工加鎖語句。通常情況下,select語句是不會對數據加鎖,妨礙影響其他的DML和DDL操作。同時,在多版本一致讀機制的支持下,select語句也不會被其他類型語句所阻礙。
借助for update子句,我們可以在應用程序的層面手工實現數據加鎖保護操作。
for update子句的默認行為就是自動啟動一個事務,借助事務的鎖機制將數據進行鎖定。
開啟一個事務使用for update
start transaction;
select sum(quantity) from ws_inventory_item where inventory_item_id=86 for update;
再開啟另一個事務時,做update 操作的時,只能等待上面的事務,commit才能執行;
start transaction;update ws_inventory_item set quantity = quantity + 1 where inventory_item_id = 86;
原文:http://www.cnblogs.com/sdgf/p/5740998.html
總結
以上是生活随笔為你收集整理的php如何解决并发问题,PHP如何解决并发问题的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SpaceX 明早将发射久违的重型猎鹰火
- 下一篇: alchemy php,Flask SQ