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个文件使用

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值