php併發加鎖

2021-07-22 14:48:09 字數 4334 閱讀 9375

clevercode在工作專案中,會遇到一些php併發訪問去修改乙個資料問題,如果這個資料不加鎖,就會造成資料的錯誤。下面clevercode將分析乙個財務支付鎖的問題。

1.1 財務支付簡化版本**

<?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);

}?>

1.2  問題分析如果有兩個操作人(p和m),都用使用者編號100賬戶,分別在pc和手機端同時登陸,100賬戶總餘額有1000,p操作人花200,m操作人花300。併發過程如下。

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

<?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.1 支付系統應用鎖

<?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);

}?>

3.2  鎖分析p操作人:

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...