当前位置:网站首页>求你了,别在高并发场景中使用悲观锁了!
求你了,别在高并发场景中使用悲观锁了!
2022-06-21 10:46:00 【Hollis Chuang】
△Hollis, 一个对Coding有着独特追求的人△

这是Hollis的第 394 篇原创分享
作者 l Hollis
来源 l Hollis(ID:hollischuang)

Hollis的新书限时折扣中,一本深入讲解Java基础的干货笔记!
我们知道,乐观锁和悲观锁是并发控制主要采用的技术手段,通常用在数据库管理中。
但是,乐观锁、悲观锁并不像行级锁、共享锁等概念一样是真实存在的锁。其实他们只是人们定义出来的概念,可以认为是一种思想。 其实不仅仅是关系型数据库系统中有乐观锁和悲观锁的概念,像memcache、hibernate、tair等都有类似的概念。
针对于不同的业务场景,应该选用不同的并发控制方式。所以,不要把乐观并发控制和悲观并发控制狭义的理解为DBMS中的概念,更不要把他们和数据中提供的锁机制(行锁、表锁、排他锁、共享锁)混为一谈。其实,在DBMS中,悲观锁正是利用数据库本身提供的锁机制来实现的。
网上有很多关于乐观锁和悲观锁的介绍,我之前也有文章(《深入理解乐观锁与悲观锁》)专门介绍过,这里为了方便大家理解,就简单做个总结。
悲观锁和乐观锁
悲观锁,正如其名,它指的是对数据被外界修改持悲观态度,因此,在整个数据处理过程中,需要先将数据进行锁定,获得锁之后再进行操作。
在MySQL中,可以使用排他锁来实现悲观锁,主要就是用到select ... for update语法。
要使用悲观锁,需要关闭mysql数据库的自动提交属性:set autocommit=0;
然后在事务中,通过如下语句对数据进行加锁:
select status from t_goods where id=1 for update以上,在对id = 1的记录修改前,先通过for update的方式进行加锁,然后再进行修改。这就是比较典型的悲观锁策略。
如果以上修改库存的代码发生并发,同一时间只有一个线程可以开启事务并获得id=1的锁,其它的事务必须等本次事务提交之后才能执行。这样我们可以保证当前的数据不会被其它事务修改。
相对悲观锁而言,乐观锁假设认为数据一般情况下不会造成冲突,所以在数据进行提交更新的时候,才会正式对数据的冲突与否进行检测,如果发现冲突了,则让返回用户错误的信息,让用户决定如何去做。
乐观锁的实现并不会使用数据库提供的锁机制。一般的实现乐观锁的方式就是记录数据版本,如以下SQL:
update t_goods
set status=2,version=version+1
where id=#{id} and version=#{version}二者区别
以上,我们了解了乐观锁和悲观锁的思想以及实现了之后,讨论一下他们的区别。
首先,在加锁时间上有所不同,悲观锁是在事务刚开始的时候就加锁,在拿到锁之后再去进行业务操作。而乐观锁是在更新的那一刻才会进行并发控制,所以是先进行的业务操作。
其次,悲观锁主要是借助数据库的排他锁实现的,而排他锁本质上是一种阻塞锁。 如果并发量比较大并且冲突比较多的时候,会导致很多线程被锁阻塞,导致请求的RT被拉长,并且会占用大量的数据库链接。
相比之下,乐观锁不会造成阻塞,但是他带来的问题就是如果并发的冲突比较高的话,那么就会有很多失败的情况,需要业务代码做好这种失败的特殊处理。
第三点,那就是乐观锁虽然叫锁,但是他并没有额外加锁,它是通过CAS来实现的,所以他的效率比较高,而悲观锁需要利用数据库的锁机制进行加锁,这会带来一定的额外消耗。
还有最后一点,也是比较重要的一点,那就是悲观锁因为做了加锁的动作,所以是会导致死锁的。
高并发不要使用悲观锁
我强烈建议大家,优先使用乐观锁,尤其是并发比较高,并且冲突也比较多的场景。
因为我们前面提到过,悲观锁会有额外的消耗、并且可能会带来死锁。但是这些都不是最重要的。
最重要的是,悲观锁本质上是一种阻塞锁,在并发比较高的情况下,会有很多个线程都被阻塞,而这些阻塞的线程是会占用数据库链接的。所以这时候就会导致你的系统的并发度很低,还有就是这些阻塞的线程的响应时长也会被拉的很长,极度影响用户体验,也会多出来很多慢SQL。
额外提一句,在MySQL 8.0中,已经支持了select ... for update nowait,可以把阻塞锁变成非阻塞的。可以在某种程度上解决悲观锁的阻塞带来的一些问题,但是加锁的额外开销和死锁的问题也还是有的。
所以,高并发场景中,建议大家使用乐观锁,尤其是MySQL 5.x 的版本中,因为不支持nowait,一旦使用悲观锁,会大大降低你的系统的并发度。

完
我的新书《深入理解Java核心技术》已经上市了,上市后一直蝉联京东畅销榜中,目前正在6折优惠中,想要入手的朋友千万不要错过哦~长按二维码即可购买~

长按扫码享受6折优惠
往期推荐还在用 SimpleDateFormat 做时间格式化?小心项目崩掉!
如果你喜欢本文,
请长按二维码,关注 Hollis.

转发至朋友圈,是对我最大的支持。
点个 在看
喜欢是一种感觉
在看是一种支持
边栏推荐
- Mqtt of NLog custom target
- 2. MySQL index creation method and its optimization
- China international e-commerce center and Analysys jointly released: the national online retail development index in the fourth quarter of 2021 increased by 0.6% year on year
- MySQL advanced - personal notes
- Intel和台积电的先进工艺阻力越来越大,中国芯片有望缩短差距
- 国金证券开户安全吗?
- Handling of legal instruction problems
- cvte一面
- Quickly analyze oom using mat tools
- ThreadLocal
猜你喜欢

CAS central certification service

03. Redis actual battle: meeting goddess nearby by geo type

The most powerful eight part essay in 2022, "code out eight part essay - cut out the offer line"

《Feature-metric Loss for Self-supervised Learning of Depth and Egomotion》论文笔记

06. Redis log: the trump card for fast recovery without fear of downtime

芯片供给过剩迹象明显,ASML不再是香饽饽,投资机构大举做空

Huawei releases wireless innovative products and solutions to build 5gigaverse Society

2. MySQL index creation method and its optimization

How to learn function test? Ali engineer teaches 4 steps

Three elements of basic concepts and methods of machine learning
随机推荐
Add solid state to the computer
2. MySQL index creation method and its optimization
Do you understand the capacity expansion mechanism of ArrayList?
K-means introduction
06. Redis log: the trump card for fast recovery without fear of downtime
EIG和沙特阿美签署谅解备忘录,扩大能源合作
Start from scratch 10- background management system development
程序員新人周一優化一行代碼,周三被勸退?
Feature metric loss for self supervised learning of depth and egomotion
is not allowed to connect to this mysql server
JobService的使用
JS regular - comb
FastAPI Web框架 [Pydantic]
Software architecture discussion
DSP online upgrade (2) -- design framework of bootloader
The bilingual live broadcast of Oriental selection is popular, and the transformation of New Oriental is beginning to take shape
ThreadLocal
Solon 1.8.3 release, cloud native microservice development framework
Use of jobservice
wangeditor封装插件初步


