这里主要使用Redis的setnx命令来处理高并发。setnx有两个参数。第一个参数代表密钥。第二个参数表示值。如果当前键不存在,则以第二个参数为值插入当前键。返回1。如果当前键存在,则返回0。CREATETABLE`storage`(`id`int(11)unsignedNOTNULLAUTO_INCREMENT,`number`int(11)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=1DEFAULTCHARSET=latin1settingCREATETABLE`order`(`id`int(11)unsignedNOTNULLAUTO_INCREMENT,`number`int(11)DEFAULTNULL,PRIMARYKEY(`id`))ENGINE=InnoDBAUTO_INCREMENT=1DEFAULTCHARSET=latin1testwithoutlock$pdo=newPDO('mysql:host=127.0.0.1;dbname=test','root','root');$sql="select`number`fromstoragewhereid=1limit1";$res=$pdo->query($sql)->fetch();$number=$res['number'];if($number>0){$sql="insertinto`order`VALUES(null,$number)";$order_id=$pdo->query($sql);if($order_id){$sql="更新存储集`number`=`number`-1WHEREid=1";$pdo->查询($sql);}}ab测试模拟并发,发现库存是正确的。mysql>从存储中选择*;+----+------+|编号|数字|+----+--------+|1|0|+----+--------+1rowinset(0.00sec)Lookingattheordertablemysql>select*from`order`;+----+-------+|编号|数字|+----+--------+|1|10||2|10||3|9||4|7||5|6||6|5||7|5||8|5||9|4||10|1|+----+--------+10rowsinset(0.00sec)发现有几个订单是操作相同的库存数据,这可能会造成超卖情况。修改代码,为数据控制添加redis锁_redis=newRedis();$this->_redis->connect('127.0.0.1');}publicstaticfunctiongetInstance(){if(self::$_instanceinstanceofself){returnself::$_instance;}returnself::$_instance=newself();}/***@functionlock*@param$key锁名*@param$expTime过期时间*/publicfunctionset($key,$expTime){//初步锁$isLock=$this->_redis->setnx($key,time()+$expTime);如果($isLock){返回真;}else{//在锁定失败的情况下。判断锁是否已经存在,如果锁已经过期,则删除锁。进行重新加锁$val=$this->_redis->get($key);如果($val&&$val
