我是靠谱客的博主 忧心战斗机,最近开发中收集的这篇文章主要介绍php 楼层加锁,php 并发加锁示例,觉得挺不错的,现在分享给大家,希望可以做个参考。

概述

大家一定会遇到当多个人同时请求一个方法时,如果涉及到金额的计算,就会出现误差,需要当一个用户在操作的时候对其方法进行加锁,减小误差,但是当5000个人同时访问时,就会出现很多用户在等待的情况,所以需要慎用。下面是对加锁的一个案例:

1,LockSystem.php文件内容

createLock($type, $options);

}

}

public function createLock($type, $options = array())

{

if (false == in_array($type, self::$_supportLocks)) {

throw new Exception("not support lock of ${type}");die;

}

//$type = "Common\Tool\AgLock\".$type;

$this->_lock = new $type($options);

}

public function getLock($key, $timeout = ILock::EXPIRE)

{

if (false == $this->_lock instanceof ILock) {

throw new Exception('false == $this->_lock instanceof ILock');

}

$this->_lock->getLock($key, $timeout);

}

public function releaseLock($key)

{

if (false == $this->_lock instanceof ILock) {

throw new Exception('false == $this->_lock instanceof ILock');

}

$this->_lock->releaseLock($key);

}

}

interface ILock

{

const EXPIRE = 5;

public function getLock($key, $timeout = self::EXPIRE);

public function releaseLock($key);

}

class FileLock implements ILock

{

private $_fp;

private $_single;

public function __construct($options)

{

if (isset($options['path']) && is_dir($options['path'])) {

$this->_lockPath = $options['path'] . '/';

} else {

$this->_lockPath = '';

}

$this->_single = isset($options['single']) ? $options['single'] : false;

}

public function getLock($key, $timeout = self::EXPIRE)

{

// $startTime = Timer::getTimeStamp();

$file = md5(__FILE__ . $key);

$this->fp = fopen($this->_lockPath . $file . '.lock', "w+");

if (true || $this->_single) {

$op = LOCK_EX + LOCK_NB;

} else {

$op = LOCK_EX;

}

if (false == flock($this->fp, $op, $a)) {

throw new Exception('failed');

}

return true;

}

public function releaseLock($key)

{

flock($this->fp, LOCK_UN);

fclose($this->fp);

}

}

class SQLLock implements ILock

{

public function __construct($options)

{

$this->_db = new mysql();

}

public function getLock($key, $timeout = self::EXPIRE)

{

$sql = "SELECT GET_LOCK('" . $key . "', '" . $timeout . "')";

$res = $this->_db->query($sql);

return $res;

}

public function releaseLock($key)

{

$sql = "SELECT RELEASE_LOCK('" . $key . "')";

return $this->_db->query($sql);

}

}

//class MemcacheLock implements ILock

//{

// public function __construct($options)

// {

//

// $this->memcache = new Memcache();

// }

//

// public function getLock($key, $timeout = self::EXPIRE)

// {

// $waitime = 20000;

// $totalWaitime = 0;

// $time = $timeout * 1000000;

// while ($totalWaitime < $time && false == $this->memcache->add($key, 1, $timeout)) {

// usleep($waitime);

// $totalWaitime += $waitime;

// }

// if ($totalWaitime >= $time)

// throw new Exception('can not get lock for waiting ' . $timeout . 's.');

//

// }

//

// public function releaseLock($key)

// {

// $this->memcache->delete($key);

// }

//}

2、locktest.php 文件

getLock($lockKey, 8);

//取出总额

$total = getUserLeftMoney($userId,$mysql);

//花费大于剩余

if ($money > $total) {

$ret = false;

} else {

//余额

$left = intval($total) - intval($money);

//更新余额

$ret = setUserLeftMoney($userId, $left,$mysql);

}

//释放锁

$lockSystem->releaseLock($lockKey);

echo "完成";

} catch (Exception $e) {

//释放锁

$lockSystem->releaseLock($lockKey);

}

}

//取出用户的余额

function getUserLeftMoney($userId,$mysql)

{

if (false == is_int($userId)) {

return 0;

}

$sql = "select account from user_account where userid = ${userId}";

$result=$mysql->query($sql);

while($s=$result->fetch_assoc()){

$b=$s['account'];

}

return $b;

}

//更新用户余额

function setUserLeftMoney($userId, $money,$mysql)

{

if (false == is_int($userId) || false == is_int($money)) {

return false;

}

$sql = "update user_account set account = ${money} where userid = ${userId}";

//$mysql = new mysql();//mysql数据库

return $mysql->query($sql);

}

?>

希望对大家有帮助,但是我还是喜欢将3中方式写成3个文件使用

最后

以上就是忧心战斗机为你收集整理的php 楼层加锁,php 并发加锁示例的全部内容,希望文章能够帮你解决php 楼层加锁,php 并发加锁示例所遇到的程序开发问题。

如果觉得靠谱客网站的内容还不错,欢迎将靠谱客网站推荐给程序员好友。

本图文内容来源于网友提供,作为学习参考使用,或来自网络收集整理,版权属于原作者所有。
点赞(40)

评论列表共有 0 条评论

立即
投稿
返回
顶部