共计 972 个字符,预计需要花费 3 分钟才能阅读完成。
在高并发的时候,我们取数据库的时候(比如抽奖机会),会导致用户只有一次机会抽多次的情况. 在这种情况,解决方式就是给整个抽奖环节加上锁处理,在使用 PHP 处理的时候我们要借助外部的资源来实现这一功能。下面我们将通过 redis 和 memcached 来实现这个功能
Redis 版本:
$redis = new Redis();
$redis->connect('127.0.0.1');
//setNx @see https://github.com/phpredis/phpredis#setnx
// 如果这个设置失败就进行循环
while(!$redis->setNx('LOCK',1)) {// 意思就是当并发的时候,设置一个锁 KEY,由于 redis 是单进程单线程,命令执行是要排队处理的,只有一个用户会成功,后续的请求处理都要等到下面的 $redis->delete('LOCK') 处理里完才会进行.
这里不做任何操作
}
// 这句话,在并发时候用户可能只有一次机会,但是由于每次请求获得的都是 1
$lottery = $this->getLotteryCount();
if ($lottery > 0) {// 这里是抽奖逻辑
$this->lottery();}
$redis->delete('LOCK');
Memcached 版本:
$m = new memcached();
$m->addServer("127.0.0.1", 11211);
do {$isLock = $m->get($lockCacheKey, null, $cas);
if ($m->getResultCode() == \Memcached::RES_NOTFOUND) {$m->add($lockCacheKey, 1);
try {// 业务逻辑,比如抽奖还有其它需要加锁的业务
} catch(Exception $e) { }
$m->delete($lockCacheKey);
} else {$isLock += 1;
$m->cas($cas, $lockCacheKey, $isLock, 300);
}
} while ($m->getResultCode() != \Memcached::RES_SUCCESS);
//memcached 实现是通过 cas 版本实现的乐观锁
// 文档地址: http://php.net/manual/zh/memcached.cas.php
正文完