高并发场景,实现一个判断库存并扣减库存的功能

我理解是防止超卖的一个场景,由于这块是高并发的场景下,频繁操作数据库,会造成性能问题,这块分两部分处理,一部分是从业务层控制冻结库存,从理财货架选择商品点击申购后,跳到收银台提交支付,在提交支付的动作里面进行剩余份额确认,当前我们是进行缓存查询,查询当前的剩余份额>申购份额时,则把这部分份额进行冻结处理,然后首先保证前端显示的剩余库存已被减掉,防止超卖。等支付成功之后,再把真实份额减掉,如果支付失败则释放冻结的份额。

另外一部分是底层数据库操作扣减库存逻辑,首先采用事务控制,我们通常会采用try, catch(rollback), commit模式在一个事物里面,在真实更新数据库的库存时,要先进行一个update操作得到真实的扣完剩余库存,再判断该值是否大于0,如果小于0则抛异常进行catch回滚,更新库存失败,保证在高并发下不会导致库存为负数。

beginTranse(开启事务)
try{
    //quantity为请求减掉的库存数量
    $dbca->query('update s_store set amount = amount - quantity where postID = 12345');
    $result = $dbca->query('select amount from s_store where postID = 12345');
    if(result->amount < 0){
       throw new Exception('库存不足');
    }
}catch($e Exception){
    rollBack(回滚)
}
commit(提交事务)

另外,更简洁的方法:

beginTranse(开启事务)
try{
    //quantity为请求减掉的库存数量
    $dbca->query('update s_store set amount = amount - quantity where amount>=quantity and postID = 12345');
}catch($e Exception){
    rollBack(回滚)
}
commit(提交事务)

我们在数据库层也会采用加锁机制(乐观锁,时间戳或者version)去控制并发修改统一记录的情况。

或者通过服务端的内存锁(锁主键)。当某个用户要修改某个id的数据时,把要修改的id存入memcache,若其他用户触发修改此id的数据时,读到memcache有这个id的值时,就阻止那个用户修改

尽量去减少数据库的大并发读写压力,通过缓存或队列方式降低读写操作。

或者针对产品名称+uid为唯一索引,控制并发。



 

猜你喜欢

转载自hujinfan.iteye.com/blog/2337904