点击下方“
IT牧场
”,选择“设为星标”
作者:iloveoverfly
来源:blog.csdn.net/new_com/article/details/105568124
在商品购买的过程中,库存的抵扣过程,一般操作如下:
-
select根据商品id查询商品的库存。
-
根据下单的数量,计算库存是否足够,如果存库不足则抛出库存不足的异常,如果库存足够,则减去扣除的库存得到最新的库存剩余值。
-
set设置最新的库存剩余值。
上述过程的伪代码如下:
select stock_remaing from stock_table where id=${goodsId};
if(stock_remaing
}
else{
int new_stock=stock_remaing - quantity;
}
update stock_table set stock_remaing =${new_stock} id=${goodsId};
# 并发修改数据库存超卖
如果数据库事务的隔离级别不是串行化(serializable),根据事务的特性,在并发修改的时候,可能会出现写覆盖的问题。
假设,商品的剩余库存stock_remaing 为100,客户A下单20,客户B下单30,在并发扣库存的时候,可能存在超卖。如果客户A和客户B同时获取剩余库存为100,则会出现事务后提交的值会覆盖前一个客户提交的值,有可能剩余的库存是80或者70。流程如下:
# 加锁更新存库
为了在事务控制中,防止写覆盖,你会想到使用select for update的方式,将该商品的库存锁住,然后执行余下的操作。