解决库存超卖/超买(事务)的问题

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/xiao__jia__jia/article/details/86375805

                    解决库存超卖/超买(事务)的问题

原因:

1 超卖出现在修改库存业务的方法中,并不是出现在数据库的更新语句中(mysql的update写操作不能并发执行)

2 业务的方法中超卖造成原因是什么,mysql的写操作和读操作可以并发执行,导致多个线程同时修改了一条库存不足的商品

解决:事务锁

悲观锁(显式锁)

select kc from t_mall_sku where id=id for update

for update 作用

那是一种行级锁,一旦用户对某个行施加了行级加锁,则该用户可以查询也可以更新被加锁的数据行,其它用户只能查询但不能更新被加锁的数据行.如果其它用户想更新该表中的数据行,则也必须对该表施加行级锁.即使多个用户对一个表均使用了共享更新,但也不允许两个事务同时对一个表进行更新,真正对表进行更新时,是以独占方式锁表,一直到提交或复原该事务为止。行锁永远是独占方式锁。
只有当出现如下之一的条件,便释放共享更新锁:
(1)、执行提交(COMMIT)语句;
(2)、退出数据库(LOG OFF)
(3)、程序停止运行。
 

乐观锁

一(弊端,其实是锁住了整条数据,后台可能会去修改该数据表该行的其他列数据,这时候下面的语句无法实现该要求)

select version from t_mall_sku where id = #{id}

update t_mall_sku set kc = kc - ?,version= version +1  where id = #{id} and version = #{version}

二(下面的做法虽然可以不影响其他列的修改,但是有弊端,假设一个商品价值10000,促销打折为100,促销活动即将结束,后台系统即将更新价格,在那瞬间,并发事件发生了,顾客在11:59:59促销结束前用100支付成功,这时商品迅速恢复原价为10000,顾客的订单消息显示为10000购买得到这个商品,银行卡只扣了一百块,这时在进行退货,不就爽了。)

select kc_version from t_mall_sku where id = #{id}

update t_mall_sku set kc = kc - ?, kc_version= kc_version +1  where id = #{id} and kc_version = #{kc_version}
 

猜你喜欢

转载自blog.csdn.net/xiao__jia__jia/article/details/86375805
今日推荐