为了账号安全,请及时绑定邮箱和手机立即绑定

php+redis抢购功能,并发问题

php+redis抢购功能,并发问题

PHP
拉风的咖菲猫 2019-03-15 08:36:11
今天尝试写并发抢购功能,再网上找了相关资料后,实现了如下: <?php #开始抢购,检测库存 $inventoryData = $this->redis->get($inventoryKey); if ($inventoryData == null) { //库存不足 return '-1'; } #解析json $inventoryData = json_decode($inventoryData, true); #检测库存 if ($inventoryData['inventory'] == 0) { //库存不足 return '-1'; } //开启事务 $this->redis->watch($inventoryKey); //事务开始 $this->redis->multi(); //将抢购数据加入redis $this->redis->lPush('kill_goods_' . $data['goods_id'], json_encode($data)); $goodsData = ['id' => $data['goods_id'], 'inventory' => $inventoryData['inventory'] - 1]; $this->redis->set($inventoryKey, json_encode($goodsData)); $result = $this->redis->exec(); if ($result) { file_put_contents('1.txt', $inventoryData['inventory'] . PHP_EOL, FILE_APPEND); return 1; } return '-1'; 经过并发测试:始终都会有重复的,请各位大佬讲解讲解
查看完整描述

4 回答

?
撒科打诨

TA贡献1934条经验 获得超2个赞

库存做原子自减

查看完整回答
反对 回复 2019-03-18
?
GCT1015

TA贡献1827条经验 获得超4个赞

用原子自减只能解决redis本身内的并发问题,但程序中并发处理也有问题。像Nine所说的一样,会存在多条访问全都通过前面的检测。必须在php程序内做原子限制。像一些高并发下的活动页面,根据实际业务做法有很多。像楼主的业务逻辑,我觉得首先可以让库存的key自减,然后直接根据返回key的值直接判断是否小于或者等于0。

查看完整回答
反对 回复 2019-03-18
?
qq_花开花谢_0

TA贡献1835条经验 获得超7个赞

我觉得这个问题可以不用事务解决的啊,还有原子自减string也是可以减为负的啊,难道负的库存也合理么?这个东西用list完美解决,根本不需要事务啊

查看完整回答
反对 回复 2019-03-18
  • 4 回答
  • 0 关注
  • 420 浏览

添加回答

举报

0/150
提交
取消
意见反馈 帮助中心 APP下载
官方微信