springboot下的悲观锁和乐观锁介绍以及相应测试

前言

关于悲观锁和乐观锁的介绍,网上一搜一大堆,可能很多人看了都是一知半解的,然后回过头就忘了、懵逼了,啥叫写为居多用悲观、读为居多用乐观?,而且并发的环境下我正常写的接口又到底会发生什么错呢?本文就模拟了1000个并发量来看看到底会发生什么情况,然后用了悲观锁和乐观锁之后又会如何呢?

两锁的简介

关于锁的简介还是要有的,简介来源:http://www.imooc.com/article/285147.
悲观锁: 悲观是我们人类一种消极的情绪,对应到锁的悲观情绪,悲观锁认为被它保护的数据是极其不安全的,每时每刻都有可能变动,一个事务拿到悲观锁后(可以理解为一个用户),其他任何事务都不能对该数据进行修改,只能等待锁被释放才可以执行。
乐观锁: 乐观锁的“乐观情绪”体现在,它认为数据的变动不会太频繁。因此,它允许多个事务同时对数据进行变动。通常用版本号的方式实现(本文也是用这个)

两锁优缺点

悲观锁
优点:1.悲观锁利用数据库中的锁机制来实现数据变化的顺序执行,这是最有效的办法
缺点:1.一个事务用悲观锁对数据加锁之后,其他事务将不能对加锁的数据 进行除了查询以外的所有操作,如果该事务执行时间很长,那么其他事务将一直等待,那势必影响我们系统的吞吐量。
乐观锁
优点:1.乐观锁不在数据库上加锁,任何事务都可以对数据进行操作,在更新时才进行校验,这样就避免了悲观锁造成的吞吐量下降的劣势。
缺点:1.乐观锁因为时通过我们人为实现的,它仅仅适用于我们自己业务中,如果有外来事务插入,那么就可能发生错误。

应用场景

悲观锁:因为悲观锁会影响系统吞吐的性能,所以适合应用在写为居多的场景下。
乐观锁:因为乐观锁就是为了避免悲观锁的弊端出现的,所以适合应用在读为居多的场景下。

好了介绍到此为止,下面开始本文正题

测试环境搭建

测试很简单,模拟事件为购买商品的时候,减去相应库存,注意这里减库存默认为-1
表结构如下
在这里插入图片描述
更新和查询语句
在这里插入图片描述
mapper
在这里插入图片描述
controller逻辑代码
在这里插入图片描述
好了下面就开始具体得测试吧,测试工具postman和jMeter

测试

无锁测试

首先把所有的锁都去掉,测试一下正常的接口在并发的情况下看看到底会发生什么
先用postman串行测试(ps:网上居然有人说postman是并发的)
在这里插入图片描述
然后调整数据库数值,来用jmeter试试1000个并发测试
在这里插入图片描述
在这里插入图片描述
为啥?因为更新分了三步:查询》减库存》更新,在并发的情况下,很大可能就是上一个用户才进行到第二步,下一个用户已经开始进行第一步了,这样很明显下一个用户取到的值并不是上一个用户更新后的,这很明显是不合理的,这就是线程安全问题(ps:这同时也证明了postman不是并发测试哦),下面让我们看看加上两锁后结果如何?

悲观锁测试

老规矩先恢复数据库测试数据,然后加上刚刚的for update,加上事务注解
在这里插入图片描述
可以看到结果正确,这是为啥?因为加上了悲观锁后,在一个用户操作的时候,即使下一用户进来了也会被阻塞,只有当上一个用户操作完了,才会继续操作,也就是达到了串行效果。让我们看看悲观锁的吞吐量
在这里插入图片描述
这玩意代表了执行效率,最后需要对比

乐观锁测试

还是一样恢复数据,删掉for updata和事务注解,加上version=#{param.version}版本判断
在这里插入图片描述
这又是为啥?首先结果是没错的,因为版本号的方式是人为控制,并不是串行的了,只是控制了是否更新,一般像这样还需要后续处理,这里就不再阐述了,再看看吞吐量
在这里插入图片描述
想必看到这里,各位已经想通很多了

总结

上面的测试已经表明了平常的接口如果不做并发量的处理后果可想而知,转化一下就可以发现本质是线程安全问题,有人说线程安全?在直接在方法上加上synchronized就好了吗?是的没错,我已经测试了加上这玩意结果也是正确了,但是你们知道这个玩意也是悲观锁吗🤣。
好了对比两锁的吞吐量你就会发现乐观锁效率比悲观锁要高,而且逻辑性越强,复杂度越高,越明显,因为悲观锁是串行的。但是乐观锁虽说效率高但是更新率很低,可以看到上面1000个并发执行的时候才更新成功198次,可以说这两种锁是各自弥补缺点,什么为什么不一起用?我只能说一起用效率是最低的,虽然各自弥补缺点,但并不是相辅相成。
这就是为什么读为居多用乐观,写为居多用悲观

上面测试仅代表个人想法,有不对的请指出,谢谢😊

评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值