本文介紹了php併發加鎖示例,對資料進行加鎖,只容許乙個使用者在乙個時間內進行操作,這個時候就需要用到鎖了,需要的朋友可以了解一下。
在工作專案中,會遇到一些php併發訪問去修改乙個資料問題,如果這個資料不加鎖,就會造成資料的錯誤。下面我將分析乙個財務支付鎖的問題。希望對大家有所幫助。
1 沒有應用鎖機制
1.1 財務支付簡化版本**
<?php1.2 問題分析如果有兩個操作人(p和m),都用使用者編號100賬戶,分別在pc和手機端同時登陸,100賬戶總餘額有1000,p操作人花200,m操作人花300。併發過程如下。/**
* pay.php
* * 支付沒有應用鎖
* * copy right (c) 2016
* * modification history:
* --------------------
* 2016/9/10, by clevercode, create
* */
//使用者支付
function pay($userid,$money)
//取出總額
$total = getuserleftmoney($userid);
//花費大於剩餘
if($money --> $total)
//餘額
$left = $total - $money;
//更新餘額
return setuserleftmoney($userid,$left);
}//取出使用者的餘額
function getuserleftmoney($userid)
$sql = "select account form user_account where userid = $";
//$mysql = new mysql();//mysql資料庫
return $mysql->query($sql);
}//更新使用者餘額
function setuserleftmoney($userid,$money)
$sql = "update user_account set account = $ where userid = $";
//$mysql = new mysql();//mysql資料庫
return $mysql->execute($sql);
}?>
p操作人:
取出使用者的餘額1000。
支付後剩餘 800 = 1000 - 200。
更新後賬戶餘額800。
m操作人:
取出使用者餘額1000。
支付後剩餘700 = 1000 - 300。
支付後賬戶餘額700。
兩次支付後,賬戶的餘額居然還有700,應該的情況是花費了500,賬戶餘額500才對。造成這個現象的根本原因,是併發的時候,p和m同時操作取到的餘額資料都是1000。
2 加鎖設計
鎖的操作一般只有兩步,一 獲取鎖(getlock);二是釋放鎖(releaselock)。但現實鎖的方式有很多種,可以是檔案方式實現;sql實現;memcache實現;根據這種場景我們考慮使用策略模式。
2.1 類圖設計如下
2.2 php原始碼設計如下
locksystem.php
<?php3 應用鎖機制3.1 支付系統應用鎖/**
* locksystem.php
* * php鎖機制
* * copy right (c) 2016
* * modification history:
* --------------------
* 2016/9/10, by clevercode, create
* */
class locksystem
} public function createlock($type, $options=array())
");}
$this->_lock = new $type($options);
} public function getlock($key, $timeout = ilock::expire)
$this->_lock->getlock($key, $timeout);
}public function releaselock($key)
$this->_lock->releaselock($key); } }
inte***ce ilock
class filelock implements ilock
else
$this->_single = isset($options['single'])?$options['single']:false;
}public function getlock($key, $timeout=self::expire)
else
if (false == flock($this->fp, $op, $a))
return true;
}public function releaselock($key)
}class sqllock implements ilock
public function getlock($key, $timeout=self::expire)
public function releaselock($key)
}class memcachelock implements ilock
public function getlock($key, $timeout=self::expire)
if ($totalwaitime >= $time)
throw new exception('can not get lock for waiting '.$timeout.'s.');
}public function releaselock($key)
<?php3.2 鎖分析p操作人:/**
* pay.php
* * 支付應用鎖
* * copy right (c) 2016
* * modification history:
* --------------------
* 2016/9/10, by clevercode, create
* */
//使用者支付
function pay($userid,$money)
tryelse
//釋放鎖
$locksystem->releaselock($lockkey);
}catch (exception $e)
}//取出使用者的餘額
function getuserleftmoney($userid)
$sql = "select account form user_account where userid = $";
//$mysql = new mysql();//mysql資料庫
return $mysql->query($sql);
}//更新使用者餘額
function setuserleftmoney($userid,$money)
$sql = "update user_account set account = $ where userid = $";
//$mysql = new mysql();//mysql資料庫
return $mysql->execute($sql);
}?>
獲取鎖:pay100
取出使用者的餘額1000。
支付後剩餘 800 = 1000 - 200。
更新後賬戶餘額800。
釋放鎖:pay100
m操作人:
等待鎖:pay100
獲取鎖:pay100
獲取餘額:800
支付後剩餘500 = 800 - 300。
支付後賬戶餘額500。
釋放鎖:pay100
兩次支付後,餘額500。非常完美了解決了併發造成的臨界區資源的訪問問題。
php併發加鎖
clevercode在工作專案中,會遇到一些php併發訪問去修改乙個資料問題,如果這個資料不加鎖,就會造成資料的錯誤。下面clevercode將分析乙個財務支付鎖的問題。1.1 財務支付簡化版本 pay.php 支付沒有應用鎖 copy right c 2016 modification histo...
debug幾法(以PHP為例)
例如,我先寫一段 echo5 0 這樣一定會出錯的,因為0不能做除數。頁面上顯示 php會直接輸出這個除以0的致命錯誤的資訊。當我們執行乙個很長的過程時出現了邏輯上的錯誤 語法上並沒有錯誤,這種bug比較難解決 一時沒有頭緒,不妨先試著輸出每個過程的執行結果,看看到底哪一步的執行脫離了預想的設計。這...
php擴充套件編譯(以memcached為例)
2 解壓並切換進入擴充套件包的目錄 3 使用phpize工具自動生成 configure 4 configure配置擴充套件 5 編譯並安裝擴充套件 下面以編譯php的memcached擴充套件來做乙個 參考 編譯memcached需要libmemcached庫,所以我們先安裝一下libmemcac...