之前的博客给小伙伴们分享了java中的锁,今天我们一起来看看mysql中有什么锁吧
一、图示
二、粒度分类
2.1、全局锁:
什么是全局锁?
MySQL的锁定主要分为全局锁、表锁和行锁。现在我们来看看MySQL全局锁。
MySQL全局锁是针对整个数据库的锁。最常用的全局锁是读锁和写锁。
2.1.1 读锁(共享锁):
它阻止其他用户更新数据,但允许他们读取数据。这在你需要在一段时间内保持数据一致性时很有用。
2.1.2 写锁(排他锁):
它阻止其他用户读取和更新数据。这在你需要修改一些大量的数据,并且不希望其他用户在这段时间内干扰时很有用。
MySQL全局锁的典型使用场景是,进行一些需要确保整个数据库一致性的操作,例如全库备份、全库导出等。
在MySQL中,可以使用 FLUSH TABLES WITH READ LOCK(FTWRL) 语句来添加全局读锁,这将阻止其他线程进行更新操作。使用UNLOCK TABLES语句来释放锁定。使用解锁表语句来释放定。
请注意,全局锁的开销非常大,因为它会阻止其他所有的数据修改操作,并且在高并发情况下可能导致大量的线程等待锁定。因此,你应该尽量避免在生产环境中使用全局锁,或者尽量减少全局锁的持有时间。
虽然全局锁有其应用场景,但是过度使用或不正确使用全局锁可能导致性能问题。因此,根据应用的特性和需求选择适合的锁策略是很重要的。对于大多数应用,优先使用更精细粒度的锁,如行锁和表锁,可以更有效的处理并发请求,同时避免全局锁的开销
2.2、表级锁
什么是表级索?
表级锁是MySQL中最基本的锁策略,是MySQL最早采用的锁策略。表级锁的特点是开销小,加锁快,不会出现死锁;锁定粒度大,发生锁冲突的概率最高,并发度最低。表锁有两种模式:
2.2.1 表共享读锁(Table Read Lock) :
又称为表读锁,允许一个事务锁定的表进行读取操作,不允许其他事务对其进行写操作,但是可以进行读操作。读锁之间是不会互相阻塞的。
2.2.2 表独占写锁(Table Write Lock) :
又称为表写锁,允许一个事务锁定的表进行读取和写入(更新)操作,但是其他任何事务都不能再对该表进行任何操作,必须等待表写锁结束。写锁会阻塞其他所有锁,包括读锁和写锁。
在MySQL中,对MyISAM表的读操作,会自动加上读锁,对MyISAM表的写操作,会自动加上写锁。
InnoDB引擎在必要情况下会使用表锁,但主要是使用行锁来实现多版本并发控制(MVCC) ,它能提供更好的并发性能和更少的锁冲突。
总的来说,表锁适用于读操作多、写操作少的应用,当并发争用不是特别激烈,以及记录级锁并发控制开销大于访问冲突开销的情况。在并发度高,或者写操作较多的情况下,表锁可能会成为瓶颈。
2.2.3 那么表级锁有哪些使用场景呢?
2.2.3.1 读密集型应用:
如果你的应用主要进行读取操作,很少进行写入操作,那么使用表级锁可能是一个好选择。因为表级读锁不会阻塞其他的读锁,所以这种场景下表级锁能够提供很高的性能。
2.2.3.2 写操作不频繁的场景:
表级锁对写操作的处理并不高效,因为一个写锁会阻塞所有其他的锁,无论它们是读锁还是写锁。但是,如果你的应用不需要频繁地进行写操作,或者可以容忍写操作的延迟,那么使用表级锁可能是可行的。
2.2.3.3 数据量不大的简单应用:
如果数据库的数据量不大,那么即使在写操作中,由于锁定整张表,对性能的影响也不大
2.2.3.4 全表更新或者删除:
在某些情况下,可能需要对一张表进行全表的更新或者删除操作,例如,删除表中的所有记录,或者更新表中所有记录的某个字段的值,在这种的情况下,使用表级锁是合适的。
但要注意,虽然表级锁的开销较小,但由于其锁定的粒度大,可能会导致并发度下降,特别是在写操作较多或者并发度较高的场景下。所以,如果应用的并发度较高,或者需要频繁进行写操作,那么可能需要考虑使用更精细粒度的锁,如行锁。
2.2.4 MySQL哪些命令会发生表级锁
2.2.4.1 ALTER TABLE:
这个命令用于更改表的结构,如添加列、删除列、改变列的类型等。执行
这个命令的时候,MySQL需要锁定整个表以防止在更改过程中有新的数据写入。
2.2.4.2 DROP TABLE 和 TRUNCATE TABLE:
这两个命令都会导致表级锁。DROP TABLE命令会
删除整个表,而TRUNCATE TABLE命令会删除表中的所有数据。在执行这些命令的时候,
MySQL需要锁定整个表以防止在删除过程中有新的数据写入。
2.2.4.3 LOCK TABLES:
这个命令可以显式地为一个或多个表加上读锁或写锁。LOCK TABLES命
令后面可以跟上一系列的表名和锁模式,用来指定需要锁定哪些表,以及使用什么样的锁模
式。例如,LOCK TABLES t1 WRITE,t2 READ;命令会给表t1加上写锁,给表t2加上读锁。
2.2.4.4 全表扫描或大范围扫描:
对于MyISAM存储引擎,全表扫描或大范围扫描会触发表级锁
2.2.4.5 FLUSH TABLES WITH READ LOCK(FTWRL):
这个命令可以给所有表加上全局读锁,其他会话在此期间不能对数据进行修改。
请注意,InnoDB存储引擎主要使用行级锁,并在一些情况下使用表级锁,比如在执行某些
ALTER TAPLE命令或者LOCK TABLES命令时。MyISAM存储引擎只支持表级锁。
2.2.5、 MySQL表锁风险点
1.性能下降:因为表锁会锁定整个表,所以在高并发的环境中,它可能导致大量的请求阻塞
从而降低性能。对于读取和写入混合密集的负载,表锁可能会成为一个性能瓶颈。
2.并发性能差:表锁的最大问题在于其并发性能。一旦一个线程对表获得了写锁,其他线程的
任何读写操作都会被阻塞,直到写锁被释放。同样的,如果一个读锁被持有,那么其他的写
操作将被阻塞。这就使得并发性能大大降低。
3.可能导致锁等待和超时:在高并发的环境中,由于表级锁的粒度较大,可能会有很多线程在
等待锁,如果等待的时间过长,可能会导致锁超时,进一步影响应用的性能和可用性。
4.写操作影响大:如果一个长时间运行的写操作(比如大数据量的UPDATE或者INSERT语
句)获取了写锁,那么会阻塞所有其他的读操作和写操作,直到这个写操作完成。
5.死锁的可能性:虽然表锁本身不会出现死锁,但在多表操作中,如果没有按照一定的顺序获
得锁,可能会导致死锁。
为了避免这些问题,我们通常会选择InnoDB存储引擎,它主要使用行级锁,可以提供更好的
并发性能,并且在一定程度上减少了锁争用的问题。而且,InnoDB还支持事务,可以保证数
据的一致性和完整性。在实际应用中,我们应该根据具体的业务需求和系统负载,选择合适的存储引擎和锁策略
2.3、行锁
2.3.1、什么是行锁?
行级锁是MVSQL中的一种锁定机制,它可以对数据库表中的单独一行进行锁定。相比于表级
锁和页锁,行级锁的粒度更小,因此在处理高并发事务时,能提供更好的并发性能和更少的锁
冲突。然而,行级锁也需要更多的内存和CPU资源,因为需要对每一行都进行管理。
在MVSQL中,行级锁主要由InnoDB存储引擎提供。InnoDB支持两种类型的行级锁:共享锁
(S锁)和排他锁(X锁)
1、共享锁(S锁):共享锁也称为读锁,它允许一个事务读取一行数据。当一行数据被共享锁锁定时,其他事务可以读取这行数据,,但不能对其进行修改。
2、排他锁(X锁):排他锁也称为写锁,它允许一个事务读取和修改一行数据。当一行数据被
排他锁锁定时,其他事务不能读取也不能修改这行数据。
在实际使用中,InnoDB还提供了一种名为“间隙锁”(Gap Lock)的特性。间隙锁不仅锁定一
个具体的行,还锁定它前后的“间隙”,即这一行之前的行和之后的行之间的空间。间隙锁可以
防止其他事务插入新的行到已锁定行的前后,从而可以解决一些并发问题。
值得注意的是:行级锁只在事务中有效,也就是说,只有在一个事务开始(BEGIN)后并在事务提交(COMMIT)或回滚(ROLLBACK)之前,才能对数据行进行锁定。如果在非事务环境中执行SQL语句,那么InnoDB会在语句执行结束后立即释放所有的锁
2.3.2 、MySQL行锁有哪些使用场景
MySQL中的行级锁(Row Level Locks)通常在以下几种场景中被使用:
1.高并发读写操作:在需要高并发读写操作的场景中,行级锁可以提高性能和并发性,因为它
允许多个事务并发地操作不同的行。
2.单行操作:对于需要操作单行数据的SQL语句(例如基于主键或者唯一索引的UPDATE、
DELETE和INSERT语句),行级锁可以提供较好的并发性和性能。
3.短期锁:在需要对数据行进行短时间锁定的情况下,行级锁可以防止长时间阻塞其他事务。
4.实现并发控制:在需要确保数据一致性和隔离性的事务中,行级锁是实现并发控制的重要机制
5.复杂的事务处理:在需要对多行数据进行复杂处理的事务中,可以使用行级锁来锁定这些
行,防止在事务处理过程中数据被其他事务修改。
使用行级锁需要注意,由于行级锁的锁定粒度较小,它可能会消耗更多的系统资源(例如内存
和CPU),特别是在处理大量数据时。此外,使用行级锁也可能导致死锁,需要使用合适的策
略来避免死锁,例如在事务中按照一定的顺序锁定行
2.3.3、MySQL那些命令会导致发生行锁?
在MySQL中,主要是InnoDB存储引擎提供了行级锁(RowLevelLocking)。一般来说,以下这些类型的操作会导致InnoDB对数据行进行加锁:
1.SELECT .. FOR UPDATE:这种查询会对选定的行添加一个排他锁(X锁),这意味着其他事务不能修改这些行,也不能对这些行添加共享锁。
2.SELECT .. LOCK IN SHARE MODE:这种查询会对选定的行添加一个共享锁(S锁),这意味着其他事务不能修改这些行,但可以对这些行添加共享锁。
3.INSERT:插入操作会对新添加的行添加一个排他锁(X锁)。
4.UPDATE:更新操作会对被更新的行添加一个排他锁(X锁)。
5.DELETE:删除操作会对被删除的行添加一个排他锁(X锁)。
这些加锁操作都是在事务中进行的,即只有在事务开始(BEGIN)后并在事务提交
(COMMIT)或回滚(ROLLBACK)之前,才会对数据行进行加锁。如果在非事务环境中执
行上述SQL语句,那么InnoDB会在语句执行结束后立即释放所有的锁。
请注意,加锁的粒度和范围取决于WHERE子句中用到的索引。如果WHERE子句中用到了唯
一索引(例如主键索引),那么InnoDB只会锁定匹配的行。如果没有用到唯一索引,那么InnoDB可可能会锁定更多的行,甚至是整个表,这就可能导致锁冲突和性能问题。
此外,InnoDB还支持间歇锁(Gap Locks)和临键锁(Next-Key Locks),这两种锁都可以在某些情况下提供更好的并发控制。
2.3.4、MySQL行锁有什么风险点?
尽管行级锁(Row-LevelLocking)可以提供高并发性并减少锁冲突,但在使用过程中也可能
遇到一些风险和问题,主要包括以下几点:
1.死锁:当两个或更多的事务相互等待对方释放资源时,就会发生死锁。例如,事务1锁定了行
A并试图锁定行B,同时事务2锁定了行B并试图锁定行A,这就形成了死锁。MVSQL会检测
到死锁并终止其中一个事务,但这仍可能导致性能问题和事务失败。
2锁升级:如果一个事务试图锁定的行过多,InnoDB可能会将锁从行级升级为表级,这就可能导致更多的锁冲突。
3锁等待:如果一个事务已经锁定了某行,其他试图访问这行的事务就必须等待,这可能导致
性能下降。如果有大量的事务在等待锁,就可能导致系统出现性能瓶颈。
4.资源消耗:行级锁需要更多的内存来存储锁信息,而且需要更多的CPU时间来处理锁请求和
释放锁。如果数据库中的行数非常多,或者并发事务的数量非常多,这可能会导致显著的资
源消耗。
5难以调试和排查:由于行级锁的粒度较小,如果出现性能问题或锁冲突,可能需要复杂的调
试和排查工作来找出问题的原因。
6.事务隔高级别:不同的事务隔离级别会影响锁的行为和性能,可能需要根据具体的应用场景来调整事务隔离级别。
为了避免上述问题,需要合理地设计数据库表和索引,合理地编写SQL语句,合理地管理事务,以及合理地设置事务隔离级别
三、模式分类
3.1、乐观锁
3.1.1 什么是乐观锁?
乐观锁(Optimistic Locking)是一种在数据库操作中用于处理并发问题的技术。它的基本思
想是假设在多个事务同时访问同一条数据时,冲突发生的概率较低,因此在操作数据时不会立
即进行锁定,而是在提交数据更改时检查是否有其他事务修改了这条数据。如果没有,就提交
更改,否则就回滚事务。
在MVSQL中,乐观锁并没有内置的实现,但是可以通过一些编程技巧来实现。一种常见的实
现方式是使用版本号(或时间戳)字段。每当一条记录被修改时,就增加版本号(或更新时间
戳)。在更新记录时,先检查版本号(或时间戳)是否和读取记录时的版本号(或时间戳)
致,如果一致则执行更新并增加版本号(或更新时间戳),否则就拒绝更新。这样就可以保证
只有当记录没有被其他事务修改时,当前事务的更改才会被提交。
乐观锁的优点在于,由于大部分时间都不需要锁定,所以在冲突较少的情况下可以获得较高的
并发性能。然而,如果冲突较多,那么乐观锁可能会导致大量的事务回滚,从而影响性能。因
此,选择使用乐观锁还是其他锁定技术,需要根据实际的并发情况和性能需求来决定。
3.1.2 乐观锁有哪些使用场景?
乐观锁(Optimistic Locking)是一种对并发控制的策略,适用于以下的应用场景:
数据并发修改的冲突较低,即同一时间内,同一条数据不会被
1.低冲突环境:在多数情况下,多个事务同时修改。
2.读多写少的场景:在读操作远多于写操作的情况下,乐观锁可以避免由于频繁的读操作导致
的不必要的锁定开销。
3.短事务操作:如果数据库的事务都是简短并且快速完成的,那么使用乐观锁可以减少因为等
待锁而导致的时间消耗。
4.分布式系统:在分布式系统中,由于网络延迟等原因,事务冲突的可能性较低,因此乐观锁
是一个合适的选择
5.互联网应用:对于互联网应用,如电子商务网站,用户浏览商品和下单等操作,多数情况下
是读取操作,且并发修改同一条数据的几率较小,因此使用乐观锁可以提高系统性能。
需要注意的是,如果事务冲突的可能性较高,或者需要长时间锁定某个资源,那么使用乐观锁
可能会导致大量的事务冲突和回滚,这种情况下,悲观锁或者其他并发控制技术可能会是更好
的选择
3.1.3、乐观锁的缺点
1.冲突检测:在高并发的环境中,乐观锁可能会导致大量的冲突。因为乐观锁只有在提交事务
时才检查是否有冲突,如果多个事务在同一时间操作同一行,那么只有一个事务能提交成
功,其他的事务都需要回滚并重新尝试,
2.处理开销:在冲突发生时,需要进行回滚和重试,这可能会增加系统的开销。在一些场景
中,这可能会导致性能下降。
3.版本管理:乐观锁通常通过版本号(或时间戳)来检测冲突。这就要求系统能够正确地管理
这些版本号,否则可能会导致错误的冲突检测
4.编程复杂性:使用乐观锁需要更复杂的编程,因为程序需要处理可能发生的冲突和重试
总的来说,乐观锁是一种有效的并发控制策略,但在冲突较多的情况下,可能会带来更大的开
销和编程复杂性,因此,是否选择使用乐观锁,需要根据应用的具体需求和场景来决定。
3.2、什么是悲观锁?
悲观锁(Pessimistic Locking)是一种并发控制的方法,基于一个假设:认为数据在并发处理过程中很可能会出现冲突。因此,为了保证数据的完整性和一致性,每次在读写数据时都会先加锁,这样可以避免其他事务进行并发的读写操作。
是否使用悲观锁需要根据应用的具体需求和场景来决定。在冲突较少,但需要保证数据完整性和一致性的情况下,可以考虑使用悲观锁。悲观锁既包括共享锁又包括排他锁,用于保证数据的独占性。
3.2.1 MySQL悲观锁适用哪些场景?
悲观锁的策略是假设数据在并发处理过程中会发生冲突,因此在进行任何读写操作前,都会预
先加锁。这种策略在某些特定的应用场景下是比较有优势的,主要包括:
1.写操作较多的场景:如果一个系统中的写操作比读操作多,或者说写操作占主导,那么悲观
锁可能是一个比较好的选择。因为在这种场景下,数据冲突的可能性相对较高,预先加锁可
以确保数据的完整性和一致性。
2.并发冲突高的场景:在并发冲突较高的场景,使用悲观锁可以避免重复尝试操作,提高系统
的整体效率。
3.业务需要强一致性的场景:在一些需要保证数据强一致性的业务场景下,例如银行转账等金
融业务,通常会选择使用悲观锁,以确保在任何情况下数据的一致性和准确性。
但是值得注意的是,悲观锁也可能引入死锁等问题,也可能因为锁定过程中事务长时间等待而
影响性能。因此,选择和使用悲观锁都需要根据具体业务场景和需求来进行。
3.2.2、MySQL如何使用悲观锁?
在MySQL中,悲观锁主要通过以下两种SQL语句实现:
1.SELECT ...FOR UPDATE:这个语句会在所选的行上设置排他锁(Exclusive Lock)。在锁定期间,其他事务无法修改这些行也无法在这些行上设置新的排他锁或共享锁。
2. SELECT ... LOCK IN SHARE MÃDE:这个语句会在所选的行上设置共享锁(Share Lock)。在锁定期间,其他事务可以读取这些行,但不能修改这些行,也不能在这些行上设置排他锁。
3.2.3、悲观锁的缺点
1.性能开销:在悲观锁机制下,锁定资源的操作会影响到系统性能。因为每次对数据的读写都需要进行加锁和解锁的操作,这会增加系统的开销,特别是在高并发的环境下,锁的竞争更是会严重影响到系统性能。
2.并发度降低:由于悲观锁在操作数据前就会加锁,这就导致了在同一时间,只有一个事务能操作数据,其他事务只能等待,大大降低了系统的并发度。
3.死锁:悲观锁在并发事务中可能导致死锁的情况发生。当两个或者更多的事务互相等待对方
释放锁时,就可能发生死锁。虽然数据库系统通常能够检测并解决死锁,但这会导致事务
滚,增加了系统的开销。
4.锁超时:如果一个事务长时间持有锁而不释放,可能导致其他等待锁的事务超时。这不仅可
能导致等待的事务失败,还可能影响到整个系统的稳定性。
因此,虽然悲观锁能有效地防止数据冲突,但由于其在并发处理中的限制,以及可能引发的问
题,如死锁、锁竞争和锁超时,我们需要根据具体的应用场景和需求,来权衡是否使用悲观锁。
四、状态分类
4.1、意向共享锁和意向排它锁
概念
意向锁是表锁,为了协调行锁和表锁的关系,支持多粒度(表锁与行锁)的锁并存。
作用
当有事务A有行锁时,MVSQL会自动为该表添加意向锁,事务B如果想申请整个表的写锁,那
么不需要遍历每一行判断是否存在行锁,而直接判断是否存在意向锁,增强性能。
4.2、为什么意向锁是表级锁呢?
当我们需要加一个排他锁时,需要根据意向锁去判断表中有没有数据行被锁定(行锁)
(1)如果意向锁是行锁,则需要遍历每一行数据去确认;
(2)如果意向锁是表锁,则只需要判断一次即可知道有没数据行被锁定,提升性能。
4.3、意向锁怎么支持表锁和行锁并存?
(1)首先明确并存的概念是指数据库同时支持表、行锁,而不是任何情况都支持一个表中同时持一个事务A持有行锁、又有一个事务表锁,因为表一旦被上了一个表级的写锁,肯定不能再上一个行级的锁。
(2)如果事务A对某一行上锁,其他事务就不可能修改这一行。这与“事务B锁住整个表就能修改表中的任意一行”形成了冲突。所以,没有意向锁的时候,让行锁与表锁共存,就会带来很多问题。于是有了意向锁的出现,如前面所言,数据库不需要在检查每一行数据是否有锁,,而是直接判断一次意向锁是否存在即可,能提升很多性能。
4.4、意向锁的兼容互斥性
五、算法分类
5.1、临键锁
什么是临检锁?
Next-Key 可以理解为一种特殊的间隙锁,也可以理解为一种特殊的算法。通过临建锁可以解决幻读的问题。 每个数据行上的非唯一索引列上都会存在一把临键锁,当某个事务持有该数据行的临键锁时,会锁住一段左开右闭间的数据。需要强调的一点是,InnoDB 中行级锁是基于索引实现的,临键锁只与非唯一索引列有关,在唯一索引列(包括主键列)上不存在临键锁
5.2、记录锁
什么是记录锁?
记录锁(Record Lock)是MySQL数据库中InnoDB存储引擎的一种锁定机制,主要用于锁定和控制对单个行记录的访问。记录锁是在索引记录上设置的,对于表没有主键或唯一索引的表,InnoDB会生成一个隐藏的聚簇索引,并在这个隐藏索引上加锁。在实际操作中,记录锁通常会在进行数据查询、更新或删除等操作时自动被数据库引擎应用例如,当执行以下查询时,MySQL会在Orders表的OrderID为1的行上设置记录锁:
记录锁主要有两种类型:共享锁(Shared Locks)和排他锁(Exclusive Locks)。共享锁(S锁)允许多个事务同时读取同一数据,但阻止任何事务进行写操作(包括该事务自身)排他锁(X锁),又称写锁,当一个事务持有排他锁时,其他事务不能读取也不能写入被锁定的数据
5.3、间歇锁
什么是间歇锁?
间隙锁(Gap Locks)是MySQL InnoDB存储引擎提供的一种锁定机制。它锁定的不是具体的行记录,而是两个索引之间的间隙(或者说区间),这样可以防止新的记录插入到该间隙,确保数据的一致性和事务的隔离性。
间隙锁常常与记录锁(Record Locks)一起使用,共同形成Next-Key锁,保护索引记录的范
围查询和扫描操作。
以下是间隙锁的主要类型:
- 区间-区间间隙锁:锁定两个索引键之间的间隙,或者是第一个索引键之前的间隙。
- 区间-记录间隙锁:锁定一个索引键和一个记录之间的间隙。
- 记录-区间间隙锁:锁定一个记录和一个索引键之间的间隙。
间隙锁的存在,主要是为了解决幻读问题。所谓幻读,是指在一个事务内读取某个范围的记录时,另外一个事务在该范围内插入了新的记录,当第一个事务再次读取该范围的记录时,会发现有些原本不存在的记录,这就是幻读。
举例来说,假设我们有一个存储学生信息的表,有一个事务A要查询年龄在10-20之间的学
生,它在查询前会对这个区间加锁。此时如果有另一个事务B想要插入一个年龄为15的学生
由于这个年龄的范围已经被事务A锁定,所以事务B必须等待,直到事务A完成,释放锁。这样
就避免了幻读的产生。
值得注意的是,由于间隙锁会锁定范围,如果并发事务较多且涉及的数据范围有交集,可能会
引发性能问题,甚至死锁。因此,在设计数据库和选择隔离级别时,需要综合考虑数据一致性
和并发性能。
5.3.1、间隙锁有哪些使用场景
间隙锁(Gap Locks)在MySQL数据库的InnoDB存储引擎中主要用于以下场景:
1.防止幻读:间隙锁的主要目的是防止其他事务在已经锁定的范围内插入新的行。这可以避免“幻读“问题,即一个事务在读取某个范围内的所有行时,另一个事务插入了一个新行,当第一个事务再次读取该范围时,会发现有一个"幻影"行。
2.范围查询:在执行范围查询时,如果事务需要对查询结果进行更新或删除,那么间隙锁可以
保证在事务执行期间,不会有新的行插入到查询范围中。
例如,以下事务会在Orders表的OrderlD列值在1到100之间的所有行上设置排他锁,并在这些
行的间隙上设置间隙锁:
3.防止死锁:在某些情况下,间隙锁可以帮助防止死锁。如果没有间隙锁,那么两个事务可能都会试图在同一位置插入一个新行,导致彼此等待对方释放锁,从而形成死锁。
需要注意的是,间隙锁在可重复读(REPEATABLE READ)和序列化(SERIALIZABLE)这两个隔离级别下才会使用,在读已提交(READCOMMITTED)和读未提交(READUNCOMMITTED)这两个隔离级别下,InnoDB不会使用间隙锁。
5.3.2、间隙锁有什么缺点?
间隙锁(Gap Locks)是MSQL的InnoDB存储引擎用于防止幻读问题的一种锁定机制,虽然
它在某些场景下非常有用,但也存在一些潜在的缺点,包括:
1性能影响:间隙锁会阻止其他事务在已经锁定的范围内插入新的行,这可能会影响到数据库
的并发性能,尤其在需要大量插入操作的高并发场景下,
2死锁风险:虽然间隙锁可以在某些情况下防止死锁,但在其他情况下,它可能会增加死锁的
风险。比如,两个事务都想在同一间隙中插入新的行,就可能发生死锁。
3.复杂性:理解间隙锁及其对事务的影响可能需要相当深入的数据库知识,尤其是在处理并发
问题和调优数据库性能时。
4.锁定范围可能过大:间隙锁锁定的是索引之间的间隙,这可能会比实际需要锁定的行要多。
如果一个事务需要锁定的只是表中的一小部分行,但由于间隙锁的存在,可能会锁定更大范
围的数据,导致不必要的锁定冲突。
请注意,以上所述的缺点主要取决于具体的使用场景和工作负载,有时候,为了保持数据的-
致性和防止并发问题,这些缺点可能是可以接受的。
到这里就结束啦,感谢小伙伴们的一路支持!!!蟹蟹!!!