当前位置:网站首页>mysql insert 时出现Deadlock死锁场景分析
mysql insert 时出现Deadlock死锁场景分析
2022-06-29 08:22:00 【蜗牛的小牛】
案例一:
有一张表A,先更新,如果影响行数为0,则执行INSERT插入数据。很常见的场景,在生产上也跑了很久,没有出现什么问题。但是有一次在测试环境做压测时居然出现了死锁,Deadlock found when trying to get lock; try restarting transaction
因为对mysql锁不熟悉,为什么insert也会死锁,不是一般在update的时候会死锁吗? 很好奇,于是开始寻找原因…
mysql锁是跟数据库设置的隔离级别有关系的,不同的隔离级别,锁也各不相同,只要是为了解决类似脏读、幻读、可重复读的问题。
select @@tx_isolation; – 查看隔离级别
隔离级别是RR(可重复读),我们知道,在此隔离级别下,为了解决幻读的问题,会有存在间隙锁和Next-key lock(行锁 + 间隙锁),即在update、delete语句后会产生间隙锁和Next-key lock,如果在并发下,存在两个事务都事前执行了UPDATE语句(各自持有了gap lock),当INSERT时,要先在插入间隙上获取插入意向锁,由于插入数据的间隙存在冲突,所以会互相等待获取插入意向锁,即相互竞争,最终会导致一方死锁。
这也解释了为什么在测试环境出现死锁。
解决:
- 不采用事务,即无事务方式执行,但是如果出现异常则会出现数据不一致的情况。
- 调整事务隔离级别为read commit,RC级别不会产生gap lock
由于我们都知道事务的重要性,所以选择第二种方式,将隔离级别改为RC。我们在生产环境一般也就这个级别,所以也解释了为什么在生产没有出现这个问题。
事务隔离级别调整可以通过spring的声明式事务方式来实现,通过注解@Transactional
@Transactional(rollbackFor = Exception.class, isolation = Isolation.READ_COMMITTED)
public void calculationEntry(List<CampaignFeedback> campaignFeedbackList, String groovyScript) {
//todo
}
再次压测,死锁问题不再出现。
案例二:
由于业务需要,经常对某张表做更新或者写入,又不想每次都先查询是否存在再插入,所以使用了mysql的replace into来实现。
replace into 语法是如果表中存在主键或者唯一索引,它会按这个维度去判断是否存在,如果存在则会先delete在insert,即它会分开两步来操作,不保证原子性。
开始使用后觉得还是很方便的,毕竟不用自己去多查询一次,mysql自动帮我们完成了。 但是到了压测环节,死锁竟然又出现了。。。。。。
因为有了前面的经验,所以这都不是问题,于是按之前的方式改了。在测试环境跑了几次都没问题,以为都是一样的问题导致,所以就上线了。
上线后,当我去验证这个功能的时候,尼玛。。。死锁问题再一次出现在我的眼前。
我很慌,为什么这次不行,难道我代码被覆盖了? 翻看git的提交记录并没有。。
于是我们去咨询了DBA,他说replace into 这个不建议使用,因为在大并发环境下,肯定会出现死锁。建议我们使用 insert into … values … on duplicate key update … 来替代
于是按DBA建议改了,再次上线后,不管怎么并发都不会出现死锁。
原因分析,如果使用replace into mysql会默认开启Gap lock和Next-key lock,所以即使加了事务配置也不起作用。
最后附上 insert into … on duplicate key update 介绍:
语法:
INSERT INTO tablename (field1,field2, field3, …) VALUES(value1, value2, value3, …) ON DUPLICATE KEY UPDATE field1=value1,field2=value2, field3=value3, …;
也可以使用以下方式(这种支持批量插入)
INSERT INTO TABLE (a,b,c) VALUES
(1,2,3),
(2,5,7),
(3,3,6),
(4,8,2)
ON DUPLICATE KEY UPDATE a=VALUES(a), b=VALUES(b),c=VALUES(c);
边栏推荐
- [untitled]
- mongoDB 持久化
- TypeScript 變量聲明 —— 類型斷言
- 今天让你知道PMP考试通过率达97%,可信不可信
- Measure the level of various chess playing activities through ELO mechanism
- ThinkPHP 6 使用 mongoDB
- 批量处理实验接触角数据-MATLAB分析
- [most complete] download and installation of various versions of PS and tutorial of small test ox knife (Photoshop CS3 ~ ~ Photoshop 2022)
- Open an account to buy funds. Is it safe to open an account through online funds-
- Speech signal processing - Fundamentals (I): basic acoustic knowledge
猜你喜欢
![[microservices openfeign] timeout of openfeign](/img/b1/9bc92250b4d544c704d2af5c08d059.png)
[microservices openfeign] timeout of openfeign
Development tips - Image Resource Management

Robcogen tutorial of robot code generator

华为设备配置中型网络WLAN基本业务

闭关修炼(二十四)浅入了解跨域问题

Matlab usage

今天让你知道PMP考试通过率达97%,可信不可信

Memoirs of actual combat: breaking the border from webshell

Baodawei of the people's Chain: break down barriers and establish a global data governance sharing and application platform

Huawei equipment is configured with small network WLAN basic services
随机推荐
Memoirs of actual combat: breaking the border from webshell
Feature selection: maximum information coefficient (MIC) [used to measure the degree of correlation between two variables X and y, linear or nonlinear strength, commonly used for feature selection of
2022 Season 6 perfect children's model Haikou competition area trial successfully concluded
New paid Tarot calculation source code (with building tutorial)
P6772 [noi2020] gourmet (matrix fast power)
Leetcode (142) - circular linked list II
搭建开源物联网平台教程
航芯开发板&调试器
The sixth season of 2022 perfect children's model Qingyuan competition area audition came to a successful conclusion
Leetcode(142)——环形链表 II
La finale de la zone de compétition Hefei de la sixième saison 2022 a été couronnée de succès.
Is it really safe to open a stock account online? Find the answer
Operating system product key viewing method
JS获取图片或base64的宽高等基本信息
Robcogen tutorial of robot code generator
Product manager certification enrollment brochure (NPDP) in July 2022
Déclaration de la variable Typescript - - assertion de type
单例模式的理解
Does the SQL server run with administrator privileges? Or run it as a normal user?
编程语言