用redis的分布式锁可以解决商品超卖的问题,简单事例(基于YII2框架):
/**
* @desc 加锁方法
*
* @param $lockName string | 锁的名字
* @param $timeout int | 锁的过期时间
* @return 成功返回identifier /失败返回false
*/
public function getLock($lockName, $timeout=10) {
#获取唯一标识符
$identifier=uniqid();
#过期时间
$timeout = intval($timeout);
#查看$lockName是否被上锁,为$lockName设置过期时间,防止死锁
if($this->redis->setnx($lockName,$identifier)) {
$this->redis->expire($lockName, $timeout);
return $identifier;
}
return false;
}
/**
* @desc 释放锁
*
* @param $lockName string | 锁名
* @param $identifier string | 锁的唯一值
*
* @param bool
*/
public function releaseLock($lockName,$identifier) {
// 判断是锁有没有被其他客户端修改
if($this->redis->get($lockName)==$identifier) {
$this->redis->multi();
$this->redis->del($lockName);
#释放锁
$this->redis->exec();
return true;
} else {
#其他客户端修改了锁,不能删除别人的锁
return false;
}
$name='Lock:goods_id';
$lockName=$name;
$identifier = $this->getLock($lockName);
if($identifier===false) {
return new \app\coffeecore\BaseApiResponse([
'code' => 1,
'msg' => '亲,该商品正在热销中,请稍后再试哦',
]);
}
/* 业务逻辑处理过程,商品生成订单减库存 */
//解锁
$this->releaseLock($lockName,$identifier);