PHP高并发下单用事务可以解决吗?

沙拉曼德 发布于 2016/06/15 13:40
阅读 417
收藏 1

一个下单的小示例(上代码,没加事务的时候):

class IndexController extends Controller { public function index(){ $stock = M('stock'); $log = M('log'); $condition['id'] = 1; if($stock->where($condition)->getField('stock_left') > 0) { $stock->where($condition)->setDec("stock_left"); $data['op'] = 1; $log->add($data);
        } else { echo "已经没剩余了";
        }
    }
}

库存默认有100个:

日志表:

Apache ab工具并发一下:
ab -n 1200 -c 1200 -w http://localhost/queue/index.php >> D:/1.html

结果出并发问题(很自然的):

然后加了事务控制之后:

class IndexController extends Controller { public function index(){ $stock = M('stock'); $log = M('log'); $condition['id'] = 1;
        M()->startTrans(); if($stock->where($condition)->getField('stock_left') > 0) { $res1 = $stock->where($condition)->setDec("stock_left"); $data['op'] = 1; $res2 = $log->add($data); if($res1 !== false && $res2) {
                M()->commit();
            } else {
                M()->rollback();
            }
        } else { echo "已经没剩余了";
        }
    }
}

再测试并发一下:
ab -n 1200 -c 1200 -w http://localhost/queue/index.php >> D:/1.html
结果呢,输出的结果没问题(但是真的解决了并发问题吗?):

很多人说了用Redis队列来做,具体实施我还是有点不太清楚,请大家帮忙

加载中
0
ruionline
ruionline
主要还是锁的问题,悲观锁,乐观锁。memcache的CAS或者REDIS WATCH。如果没记错的话 微信红包也是使用了memcache的CAS
0
0
彩虹糖tang
彩虹糖tang
mark,坐等大神回答
0
工兵铲
工兵铲

DB->start_trans();

$res=DB->query("update tb_stock set stock_left=stock_left-1 where stock_left>0 and id=1");

if(!$res){

    DB->rollback();

    exit("库存不足");

}

DB->commit();

返回顶部
顶部