PHP抽奖活动加内存锁,原理是什么?如何实现?
public function acquire($key) {
//如果需要同时获取两个锁
if ( is_array($key) && count($key) == 2 ) {
while (TRUE) {
$res = array();
foreach($key as $k => $v) {
$res[$k] = $this->acquire($v);
if ( !$res[$k] ) {
break;
}
}
//若第一个锁未拿到则直接返回
if ( !$res[0] ) {
$err = new SysErr(System::MEMCACHE_ACQUIRE_LOCK_ERROR);
ErrorHandle::throwErr($err);
} elseif( !$res[1] ) {
//释放第一个锁,等待然后重试
$this->release($key[0]);
usleep(LockConfig::LOCK_TIMEWAIT);
} else {
return TRUE;
}
}
} else {
$lock_key = LockConfig::LOCK_PREFIX . $key;
$i = 0;
do {
$lock = $this->_memcache->add( $lock_key, 1, LockConfig::LOCK_TIMEOUT );
//如果第一次没有获取到锁则等待指定时间后重试
if ($i > 0) {
usleep(LockConfig::LOCK_TIMEWAIT);
}
$i++;
//超过重试次数后退出
if ($i > LockConfig::LOCK_RETRY_TIMES) {
$err = new SysErr(System::MEMCACHE_ACQUIRE_LOCK_ERROR);
ErrorHandle::throwErr($err);
}
} while( !$lock );
// 记录log
if ($i > 1) {
LogHelper::warning('lock.log', "Acquire lock '{$lock_key}' for {$i} times");
}
return $lock;
}
}
/**
* 释放内存锁
*
* @param string $key 内存锁去除前缀后的key值
* @return bool 释放成功返回TRUE
*/
public function release($key) {
$lock_key = LockConfig::LOCK_PREFIX . $key;
return $this->_memcache->delete($lock_key);
}
为情所困2017-05-16 13:11:23
宝くじにはメモリーロックは必要ありません。 Redis キューまたはトランザクションを使用して、Mysql ロックを追加できる必要があります。 。
あなたが望むメモリロックがこれであるかどうかはわかりません:
$lock = new CacheLock('key_name');
//ここにロジック
$lock->unlock( );
CacheLock プロセス ロックは、主に、キャッシュが過剰な SQL リクエストのデータベースへの侵入を防ぐことができない場合の単一プロセスのキャッシュ取得に使用され、同時実行中の PHP のロック制御を解決し、ファイルを介してプロセス間ロックを実行します。そうでない場合、eaccelerator を使用してファイル ロックを処理し、対応するディレクトリに対応する粒度でロックを生成します。eaccelerator を使用すると、行と同様に、異なるロックが並行して実行されます。 mysql innodb の -level ロック。