clevercode在工作專案中,會遇到一些php併發訪問去修改乙個資料問題,如果這個資料不加鎖,就會造成資料的錯誤。下面clevercode將分析乙個財務支付鎖的問題。
1.1 財務支付簡化版本**
1.2 問題分析如果有兩個操作人(p和m),都用使用者編號100賬戶,分別在pc和手機端同時登陸,100賬戶總餘額有1000,p操作人花200,m操作人花300。併發過程如下。<?php
/**
* 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操作人:
1 取出使用者的餘額1000。
2 支付後剩餘 800 = 1000 - 200。
3 更新後賬戶餘額800。
m操作人:
1 取出使用者餘額1000。
2 支付後剩餘700 = 1000 - 300。
3 支付後賬戶餘額700。
兩次支付後,賬戶的餘額居然還有700,應該的情況是花費了500,賬戶餘額500才對。造成這個現象的根本原因,是併發的時候,p和m同時操作取到的餘額資料都是1000。
鎖的操作一般只有兩步,一 獲取鎖(getlock);二是釋放鎖(releaselock)。但現實鎖的方式有很多種,可以是檔案方式實現;sql實現;memcache實現;根據這種場景我們考慮使用策略模式。
2.1 類圖設計如下
2.2 php原始碼設計如下
locksystem.php
3.1 支付系統應用鎖<?php
/**
* 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)
}
3.2 鎖分析p操作人:<?php
/**
* 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);
}?>
1 獲取鎖:pay100
2 取出使用者的餘額1000。
3 支付後剩餘 800 = 1000 - 200。
4 更新後賬戶餘額800。
5 釋放鎖:pay100
m操作人:
1 等待鎖:pay100
2 獲取鎖:pay100
3 獲取餘額:800
4 支付後剩餘500 = 800 - 300。
5 支付後賬戶餘額500。
6 釋放鎖:pay100
兩次支付後,餘額500。非常完美了解決了併發造成的臨界區資源的訪問問題。
php併發加鎖以支付為例
本文介紹了php併發加鎖示例,對資料進行加鎖,只容許乙個使用者在乙個時間內進行操作,這個時候就需要用到鎖了,需要的朋友可以了解一下。在工作專案中,會遇到一些php併發訪問去修改乙個資料問題,如果這個資料不加鎖,就會造成資料的錯誤。下面我將分析乙個財務支付鎖的問題。希望對大家有所幫助。1 沒有應用鎖機...
事務併發 併發控制(加鎖)
事務處理中的併發控制 1.併發操作 資料庫是乙個共享資源,允許多個使用者程式並行地訪問資料庫,所以當多個使用者併發地訪問同一資料,就可能出現資料的不一致性。例如 假設有兩個事務 t1 和 t2 它們都需要讀出並修改資料 a 其執 況如下所示 執行順序 1 2 3 4 5 6 事務t1 讀aa a 1...
併發取主鍵 加鎖
create procedure up newtableid tcode varchar 20 nextid intoutput as declare curtkey int,nexttkey int begin tran transid select curtkey tkey from keyta...