超卖现象的解决办法及单体应用锁详解

一、超卖现象

举例1:

某商品库存数量10件,结果卖出了15件。

商品的卖出数量超出了库存数量,这肯定不行。

产生原因

在这里插入图片描述
在这里插入图片描述

图解

在这里插入图片描述

解决办法1

在这里插入图片描述

解决办法1的代码实现
  1. 首先有3张表,order,order_item,product
    product表的字段:
    在这里插入图片描述
    product表的数据:
    在这里插入图片描述

  2. order表的字段:
    在这里插入图片描述

  3. order_item表的字段:
    在这里插入图片描述

代码:

在这里插入图片描述

在这里插入图片描述
在这里插入图片描述

在多线程并发的情况下,会产生超卖现象。

利用方法1,不在程序中扣减库存,解决问题。
在这里插入图片描述
在这里插入图片描述

这个方法还不能解决问题,同时下5个单,商品会变成负数。

超卖现象举例2

商品变成负数

产生原因

并发监测库存,造成库存充足的假象。
update更新库存,导致库存变成负数。

图解

在这里插入图片描述

解决方法
方法1:1

可以先使用最简单的方法,在更新商品数量后,再校验商品的库存,如果是负数,抛出异常。

方法2: 加锁 synchronized

在校验库存和扣减库存统一加锁,使之成为原子性操作,并发的时候,只有获取到锁的线程才能校验扣减库存。
在扣减库存结束后释放锁,确保库存不会变成负数。

可以使用synchronized关键字解决超卖问题,这是最原始的锁哦。

  1. 如果在创建订单的方法上加synchronized关键字,这样能够解决问题吗?

答案是不能的,因为锁住的是当前方法,但是事务没有被锁住,线程1的锁释放后,线程2进入该方法,事务可能还没提交,这就导致了查询库存的时候,还是原来的库存。

  1. 那么如何控制事务呢?

这个时候就要手动的控制事务

  • 首选注入平台事务管理器
    在这里插入图片描述
  • 注入事务定义
    在这里插入图片描述
  • 在方法的前面创建事务
    在这里插入图片描述
  • 在方法的最后提交事务
    在这里插入图片描述

在异常的地方进行事务的回滚
在这里插入图片描述

解决方法2

利用synchronized块 解决问题 。
和方法1类似,就不多说了,在synchronized块中可以是对象,也可以是类,this代表的是当前类的对象,要保证是单例的。

方法3: 加锁 reentrantlock(并发包里的锁,可重入锁)

在这里插入图片描述
在这里插入图片描述

然后在并发的地方加上lock.lock();,在事务提交之后加上lock.unlock();
还要把要并发的地方加上try,catch,finally,在finally里加上lock.unlock(); ,防止锁没有被释放。

评论 6 您还未登录,请先 登录 后发表或查看评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
©️2022 CSDN 皮肤主题:鲸 设计师:meimeiellie 返回首页

打赏作者

逸羽菲

你的鼓励将是我创作的最大动力

¥2 ¥4 ¥6 ¥10 ¥20
输入1-500的整数
余额支付 (余额:-- )
扫码支付
扫码支付:¥2
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、C币套餐、付费专栏及课程。

余额充值