乐观锁的使用场景以及失效问题

文章目录

一、乐观锁的基本概念

乐观锁适用于写少读多的情况下(多读场景),即冲突真的很少发生的时候,这样可以省去了锁的开销,加大了系统的整个吞吐量

乐观锁实现方式通常有两种 1是通过mybaits配置version版本号的方式 2是通过数据库中根据更新时间使用时间戳的方式

二、讲解下乐观锁失效和成功的场景问题

1.乐观锁失效的场景:

先说下下面这段代码的简单执行流程:
因为是自己的本地去执行 没办法去实现分布式项目运行的整个过程 所以也只能模拟执行流程 但是大体执行过程是不变的
下面是给大家演示的乐观锁失效的过程
因为项目是分布式项目 本人暂时模拟不了线上的环境所以只能以自己模拟的方式给大家展示(1乐观锁失效的场景)

模拟剩余库存数:
在这里插入图片描述
项目中的执行代码如下:
在这里插入图片描述

1 首先这段代码要开启事务

2 模拟分布式并发下两台机器同时请求查询库存的情况

3 两台服务器同时查找到了相同数据 相当于下面这个goodsSkus集合存储了两条相同的数据(并发查找到)

4 查找到的库存数都为1也就是我们数据库里面的库存数剩为1的库存(这个很重要都拿到了最后一个商品)

5 接下来都做库存减1操作 那么每条数据执行完都是用自己拿到的库存为1的值 进行减1操作 所以两天数据分别执行后库存都为0

6 那么根据乐观锁的定义就是说

1.如果第一条数据根据id和版本号执行完修改操作后版本号就会加1
2.第二条数据根据id和版本号在去更新会失败 所以第二条的rsult应该为false 这样才符合正常扣减库存 不出现超卖的现象

7 结论 两条数据的result 都为true 所以说库存扣减一次的情况下有两单商品下单成功了 也就是说这就是乐观锁下出现的库存超卖的问题

上面代码运行完的结果如下图都成功了也就是出现了超卖问题
在这里插入图片描述
数据库中的库存数为:
在这里插入图片描述

2.乐观锁生效的场景(去掉事务)

模拟剩余库存数
在这里插入图片描述

和乐观锁失效场景不同的是 下面开发测试的这段代码去掉了事务 过程和上面乐观锁失效代码是一样的 (除了没有事务) 但是执行结果会有差异哦!

在这里插入图片描述
来看下最后的执行结果 第一条执行的结果为ture 也就是修改成功 第二条执行的结果为false 也就是执行修改失败了 那么和我们的预期是相符合的下单没有出现超卖的现象 结果和我们预想的是一样的 开启事务在分布式项目并发下单下 会出现库存超卖的问题 最后使用乐观锁尽量不要在事务下使用并发下会有问题哦在这里插入图片描述
最后看下数据库更新的结果为下图 库存已经更新为0了
在这里插入图片描述

3.简单讲解下悲观锁中的排它锁for update行锁的方式防止分布式并发下同时修改同一条数据的问题

首先开启事务

两条请求同时打进来的情况下 使用for update查询 第一条请求会正常执行 第二条请求会等待一条请求执行完提交事务后在继续执行(使用的是数据库行锁的方式执行)看下代码的简单执行过程

在这里插入图片描述
这面的这段代码使用了数据库行锁的方式去执行 解决了分布式项目并发下 库存超卖的问题 有兴趣的小伙伴可以自己了解操作下 这里我就不过多说明了我有一篇关于 fou update排它锁的问题感兴趣的小伙伴可以自己去看看

总结

在这篇文章中我主要为大家讲解了分布式项目并发下库存超卖的问题 并且都是自己的亲身经历有问题的小伙伴可以自己去看下 喜欢的话就给个关注加点赞转发哈

  • 1
    点赞
  • 7
    收藏
    觉得还不错? 一键收藏
  • 8
    评论
Spring事务失效场景主要有以下几种: 1. 事务传播属性设置错误:Spring中的事务传播属性指定了事务方法调用其他事务方法时,事务如何传播。如果事务传播属性设置错误,事务可能会失效。例如,设置了Propagation.REQUIRED_NEW属性的方法在调用其他事务方法时,会将当前事务挂起,新开一个事务,如果调用的方法没有使用事务注解,则新开的事务会失效。 2. 异常被捕获并处理:如果在事务方法中捕获了异常并进行了处理,事务可能会因为异常被处理而不回滚。例如,在try-catch块中捕获了异常并使用了Logger输出异常信息,而没有将异常再次抛出,这样事务就不会回滚。 3. 事务方法中使用了ThreadLocal:ThreadLocal是线程局部变量,它可以在当前线程中存储数据,但是在事务方法中使用ThreadLocal可能会导致事务失效。因为ThreadLocal存储的数据只在当前线程中可见,如果在事务方法中使用了ThreadLocal存储了一些数据,但在事务提交时这些数据并没有被清空,那么这些数据将会影响到下一次事务的执行,从而导致事务失效。 4. 数据库引擎不支持事务:有些数据库引擎不支持事务,例如MyISAM引擎,如果在使用这些引擎的表上执行事务操作,事务将会失效。 5. 并发情况下使用乐观锁:在并发情况下,如果事务方法中使用乐观锁,可能会导致事务失效。因为在事务提交时,如果数据已经被其他事务修改过,那么乐观锁会认为数据没有被修改过,从而导致事务提交失败。 需要注意的是,以上场景只是一些常见的情况,实际上事务失效的原因可能是多种多样的,需要具体问题具体分析。
评论 8
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值