闲谈mysql三种行锁(记录锁、间隙锁与临键锁)

一个记录键只是一条记录。
唯一索引的精确匹配添加此键。

间隙锁锁定范围。
对非唯一索引使用 BETWEEN。
无法将新记录添加到该范围中。

Key lock pro是最特别的。
解决鬼读问题。
左阀锁打开,右阀关闭。

所有三种类型的键都依赖于索引。
如果没有索引,表键就会改变。

Pro键锁和间隙锁触点。
对于非唯一索引使用相同的条件。

如何锁钥匙锁?如何计算间隔?

mysql幻读怎么解决

说实话,我一直对 MySQL 的幻读感到非常头疼,尤其是与不可重复读混淆时。
我记得当时我正在研究电子商务系统的订单号生成逻辑。
测试环境报错,因为幻读的逻辑没有理解。
我花了很长时间排查,发现隔离级别没有调整正确。

最直接的方法就是直接将事务隔离级别调整为SERIALIZABLE。
这样其实可以彻底解决幻读问题。
由于这是最高的隔离级别,InnoDB自动为每个SELECT添加一个X锁,无论是行锁还是间隙锁。
我以前在一个金融项目上做过这个。
当时表的数据量不是很大,但是业务要求很严格,所以我们选择了SERIALIZABLE。
结果,并发性的增加使整个系统变得像蜗牛一样缓慢,而且无可否认,成本有点高。
因此,老实说,我不建议轻易调整到这个级别,除非你绝对必须使用它。

有趣的是,REPEATABLE-READ (RR) 的默认隔离级别实际上是可以调整的,但必须手动锁定。
我通常使用的是 SELECT ... FOR UPDATE,例如检查用户 ID。
添加这条语句后,InnoDB会自动锁定它。
如果 ID 存在,则添加行锁。
如果不存在,请添加一个间隙锁来锁定附近的 ID 范围。
这就好像给你的数据加了一个临时的保护罩,让其他事务暂时无法在这里插入数据。
我之前在我的用户注册模块中使用过这个。
我在检测到用户名是否存在后立即添加了 FOR UPDATE。
这有效地防止了两个并发请求同时注册相同的用户名。
但请注意,这个锁是基于索引的。
如果查询条件未建立索引,则锁的效率较低。

我必须在这里澄清一个误会。
许多人将幻读与不可重复阅读混为一谈。
事实上,它们根本不是一回事。
幻读的关键是“读写”争用。
这意味着事务A读完后,事务B插入新数据,A的后续操作失败。
例如,如果您检查 id=1 不存在并想要插入一条记录,但该记录首先由另​​一个事务插入,则应该报告主键冲突。
这种由于读取结果发生变化而导致操作失败的情况称为幻读。
对于不可重复读,简单来说就是两次读的结果不同,但是没有插入操作。

坦率地说,您选择哪种解决方案取决于您的业务这取决于您的需求。
如果数据一致性至上,并发量不高,直接使用SERIALIZABLE。
如果您同时需要安全性和性能,请在 RR 级别手动锁定 SELECT 键。
我记得在一个项目中,我建议在生成订单号时在业务方面添加 FOR UPDATE。
在测试过程中,我发现并发量提升确实有点慢,但最终安全性更重要。

我个人没有运行过像分布式事务这样的复杂场景,但我确实记得数据是关于 X 的,但我建议检查一下。
也就是说,只有了解幻读的基本原理,才能选择最合适的解决方案。

MySQL 是怎么加行级锁的?为什么一会是 next-key 锁,一会是间隙锁,一会又是记录锁?

上星期。
我检查了MySQL锁信息。

行级别的锁。
确实有一个模型。

正常选择。
畅通。

锁定读操作。
它将被锁定。

例如,选择...FORUPDATE。

或选择...锁定共享模式。

这些陈述。
如果你想使用它。

必须先开业。
开始或开始交易。

行级锁定的类型。
记录锁定、间隙锁定、下一个键锁定。

已阅读已提交。
仅保存锁。

可重复阅读。
有记录锁。
还有一个限位锁。

防止鬼读。

Next-KeyLock。
结合记录锁和空间锁。

保护文件夹本身。

防止插入新记录。

封锁决定。
查看SQL语句类型。

看看索引的使用。

查看查询条件。

查看隔离级别。

例如,查询相当于唯一索引。

录音已存在。
添加记录锁。

该文件夹不存在。
添加空间锁定。

范围查询。
锁的类型也会改变。

查看查询条件。
看数据分布。

分析锁类型。

可以检查SQL。

例如,SELECTFROMperformance_schema.data_locks;
锁定规则。
看一下SQL语句。

查看索引。

查看查询条件。

查看隔离级别。

了解规则。

管理业务。
非常重要。

避免全表锁。

提高性能。

我不确定这部分。
具体版本效果。

但是基本原则。
应该是差不多的。

算了。