Mysql间隙锁死锁避免最佳实践

2024-06-06 20:36

本文主要是介绍Mysql间隙锁死锁避免最佳实践,希望对大家解决编程问题提供一定的参考价值,需要的开发者们随着小编来一起学习吧!

最近写代码的时候听说,批量操作提高死锁的概率,但是心里又想,为什么没看到任何一款数据库相关的中间价禁止或者提醒批量操作?心里想肯定是因为一起其他操作的不当导致的死锁问题。进行了一些思考,希望可以帮助到大家

Mysql死锁的根本原因

死锁诞生的四个必要条件,这个是理论的基础,这个就不讲了,看下最常见也是开发中最容易导致的死锁问题。

很多大厂为了提高性能,会把RR隔离级别改为RC隔离级别,取消了间隙锁,提高性能的同时也大大避免了死锁的概率。

而RR相比RC隔离级别,主要就是间隙锁这个玩意儿,解决当前读时(每次获取最新的数据,而不是快照)的幻读问题,当然并没有完全解决,这个自己去探究,和本文关系不大。

1.为什么说高并发大厂改为RC隔离级别,速度就提高了,死锁概率也大大降低了?

2.对于大多数公司,并没有极高的并发,就是采用RR隔离级别,应该怎么做,才能减少因间隙锁导致的死锁问题呢?

到这里就有答案了:大多数mysql遇到的死锁都是因为RR隔离级别,需要通过间隙锁,解决幻读问题,开发人员又没充分的理解间隙锁何时会加,怎么避免不必要的加间隙锁,而导致的死锁问题;

Mysql何时会加间隙锁?

想要避免因间隙锁死锁导致的问题,首先,要弄清究竟什么时候会加间隙锁?

对于delete 、 update、select xxx for update带有加锁性质的语句,会加间隙锁。至于怎么加?为什么加间隙锁就死锁了,听我慢慢讲。

1.如果这些语句没走索引,网上我看很多文章都说,不走索引,就会加表锁。。。这纯属于瞎扯。

这是因为加next-lock临键锁,没走索引,发生了全表扫描,整个表都加上了锁,整个表的间隙都加上了间隙锁,也就是整个表加了临键锁(间隙锁+记录锁)

2.如果走了索引:会因为这个情况加锁,而且死锁:(这是通用的间隙锁死锁原因):

间隙锁是并不是互斥的,事务1给一段范围加了间隙锁,事务2也可以给这段范围加间隙锁,互斥的是插入意向锁和间隙锁互斥,正常来说就是:事务1加了间隙锁,事务2插入的时候会生成一个插入意向锁,这样就避免了幻读问题。

不正常的时候就是事务1加了间隙锁,事务2在同样的范围也加了间隙锁,进行操作的时候,两个事务就会死锁了,比如事务1插入,被事务2的间隙锁阻塞,事务2插入,被事务1的间隙锁插入。

死锁例子:事务1执行加了间隙锁       

                                                        事务2执行加了间隙锁

                事务1插入记录(阻塞)

                                                         事务2插入记录(阻塞)   死锁发生了。

这样的例子很多。

比如:

(1) 表的数据有 1。 2   3。

        事务1,删除4,加临键锁(3,正无穷]       

                                                                        事务2,删除5,加临键锁(3,正无穷]

        事务1。insert。  4(阻塞)

                                                                        事务1。insert。  4(阻塞)

(2) 加锁读:1,2,3

        事务1。select 4 for update      加临键锁(3,正无穷] 
                                                                             事务2,  select 5 for update  加临键锁(3,正无穷] 

        事务1。insert。  4(阻塞)                                   事务1。insert。  4(阻塞)

(3)更新同上

(4)(5)(6)

这里只是间隙锁死锁,insert可以换成是其他操作,delete。update可以探究下是否会阻塞死锁。

大致的加锁就是这样。

可以看到上面的例子,大多是对于不存在的操作进行改变,不存在,就一定会加间隙锁。

如何避免间隙锁死锁?

暴力就是有大厂类似需求的,不用RR,就不会有间隙锁死锁。(不推荐,大多数公司用不了)

通过上面的分析:

避免死锁死锁有这些最佳实践

1.删除、更新之前,先判断在不在,不在的数据,进行删除更新,虽然不会报错(返回0rows)但是。操作一定会加间隙锁。开发人员要避免这种情况

2.尽量通过主键操作,先查出主键,再进行删、改操作,就只会加行锁,不会加间隙锁

3.一定要保证这些加锁的语句走了索引,不走索引的话,会导致整个表加锁,整个表的间隙也加锁,是很多next-lock锁,而不是表锁!

4.仅仅真的涉及幻读问题的时候,才让间隙锁去发挥他的作用,比如selet for update,语句需要的时候,大多数场景用不到间隙锁,就开发的时候避免掉这些间隙锁,也就是尽量遵循上面1 2 3逻辑。

还有就是尽量少量批量了,上面4条降低死锁,这一条就尽量让事务快速的执行完,减少多个事务并发,持有相同的间隙锁。

这篇关于Mysql间隙锁死锁避免最佳实践的文章就介绍到这儿,希望我们推荐的文章对编程师们有所帮助!


原文地址:
本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若转载,请注明出处:http://www.chinasem.cn/article/1037167

相关文章

浅谈mysql的not exists走不走索引

《浅谈mysql的notexists走不走索引》在MySQL中,​NOTEXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引,下面就来介绍一下mysql的notexists走不走索... 在mysql中,​NOT EXISTS子句是否使用索引取决于子查询中关联字段是否建立了合适的索引。以下

Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式

《Java通过驱动包(jar包)连接MySQL数据库的步骤总结及验证方式》本文详细介绍如何使用Java通过JDBC连接MySQL数据库,包括下载驱动、配置Eclipse环境、检测数据库连接等关键步骤,... 目录一、下载驱动包二、放jar包三、检测数据库连接JavaJava 如何使用 JDBC 连接 mys

SQL中如何添加数据(常见方法及示例)

《SQL中如何添加数据(常见方法及示例)》SQL全称为StructuredQueryLanguage,是一种用于管理关系数据库的标准编程语言,下面给大家介绍SQL中如何添加数据,感兴趣的朋友一起看看吧... 目录在mysql中,有多种方法可以添加数据。以下是一些常见的方法及其示例。1. 使用INSERT I

Qt使用QSqlDatabase连接MySQL实现增删改查功能

《Qt使用QSqlDatabase连接MySQL实现增删改查功能》这篇文章主要为大家详细介绍了Qt如何使用QSqlDatabase连接MySQL实现增删改查功能,文中的示例代码讲解详细,感兴趣的小伙伴... 目录一、创建数据表二、连接mysql数据库三、封装成一个完整的轻量级 ORM 风格类3.1 表结构

MySQL 中的 CAST 函数详解及常见用法

《MySQL中的CAST函数详解及常见用法》CAST函数是MySQL中用于数据类型转换的重要函数,它允许你将一个值从一种数据类型转换为另一种数据类型,本文给大家介绍MySQL中的CAST... 目录mysql 中的 CAST 函数详解一、基本语法二、支持的数据类型三、常见用法示例1. 字符串转数字2. 数字

Spring WebFlux 与 WebClient 使用指南及最佳实践

《SpringWebFlux与WebClient使用指南及最佳实践》WebClient是SpringWebFlux模块提供的非阻塞、响应式HTTP客户端,基于ProjectReactor实现,... 目录Spring WebFlux 与 WebClient 使用指南1. WebClient 概述2. 核心依

Mysql实现范围分区表(新增、删除、重组、查看)

《Mysql实现范围分区表(新增、删除、重组、查看)》MySQL分区表的四种类型(范围、哈希、列表、键值),主要介绍了范围分区的创建、查询、添加、删除及重组织操作,具有一定的参考价值,感兴趣的可以了解... 目录一、mysql分区表分类二、范围分区(Range Partitioning1、新建分区表:2、分

MySQL 定时新增分区的实现示例

《MySQL定时新增分区的实现示例》本文主要介绍了通过存储过程和定时任务实现MySQL分区的自动创建,解决大数据量下手动维护的繁琐问题,具有一定的参考价值,感兴趣的可以了解一下... mysql创建好分区之后,有时候会需要自动创建分区。比如,一些表数据量非常大,有些数据是热点数据,按照日期分区MululbU

SQL Server配置管理器无法打开的四种解决方法

《SQLServer配置管理器无法打开的四种解决方法》本文总结了SQLServer配置管理器无法打开的四种解决方法,文中通过图文示例介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的... 目录方法一:桌面图标进入方法二:运行窗口进入检查版本号对照表php方法三:查找文件路径方法四:检查 S

MyBatis-Plus 中 nested() 与 and() 方法详解(最佳实践场景)

《MyBatis-Plus中nested()与and()方法详解(最佳实践场景)》在MyBatis-Plus的条件构造器中,nested()和and()都是用于构建复杂查询条件的关键方法,但... 目录MyBATis-Plus 中nested()与and()方法详解一、核心区别对比二、方法详解1.and()