mysql分布式事务解决方案
分布式事务也是面试的一个高频知识点。1. 事务基本概念1.1 什么是事务?事务是恢复和并发控制的基本单位,事务有四个特性(ACID),原子性(Atomicity),一致性(Consistency),隔...
2024.11.15幻读:侧重于insert、delete这种操作,第一次查出生成视图之后,即便有别的事务insert、delete,也不影响后续的查询。
首先解释下本次涉及的3种锁:
X锁:俗称写锁/排他锁,即加锁之后,不允许别的事务来修改当前数据。GAP锁:俗称间隙锁,就是锁住某个范围(RR级别解决幻读的关键)Next-Key锁:GAP锁+记录本身着重强调一下,所有锁,都是针对索引的,锁的是索引,记住。如果没有索引,那就芭比Q了。
八股文:B+tree:非叶子节点只存储索引,所有叶子节点之间都有一个链指针,不存储数据,数据记录都存放在叶子节点中。
如下图所示:
上面是B+tree的数据结构,一定要记住叶子节点,里面包含了索引和data(主键/其他数据)。
有一点需要说明:叶子节点是按页存储的,页之间是双向链表,页里面的叶子节点是单向链表。
来个预热:
场景:1:表结构(id是主键,count为普通索引):
开启事务1:
先查询count = 5,生成视图。
开始事务2:
此时插入一条count = 4的数据,很明显,被阻塞住了。
为啥要阻塞count = 4的记录呢?因为RR级别下,其实是加了GAP锁,不允许插入某个范围的值,从而避免了幻读的出现,那么这个范围是怎么定义的呢?
这是官网的,应用于我上面的例子,锁住的就是(3,5],(5,7],左开右闭。
好了,大家都散了吧。结论已经得出了:
加了范围锁,不允许插入数据,所以不会出现幻读的情况,范围如上。
什么,你反对?
对于GAP的范围,看到网上很多讨论,有的说是测试的左开右闭,也有说测试的左闭右开。
这里,我想说,虽然实践是检验真理的标准,但是实践的前提是,你得明白实践方式对不对。
好,我们继续,上面的测试情况:
可以具体成上图,因为是普通索引,所以data只包含了主键。
那么锁住的是哪一块呢?
锁的其实是上述的区间,而左开右闭,左闭右开都是错误的。要看插入的位置
超出那个区间的就可以插入,反之即不可以插入,这个位置是按主键排序的。
count=3,id=32,可以插入count=3,id=34,不可以插入count=7,id=76,不可以插入count=7,id=78,可以插入我们可以验证一下:
1.count=3,id=32:
插入成功,没有阻塞。
2.count=3,id=34:
插入失败,阻塞。
3.count=7,id=76:
插入失败,阻塞。
4.count=7,id=78:
插入成功,没有阻塞。
验证GAP:
这下是真的结束了,大家可以散了。
什么?还没走?那么来传授一个面试装13技巧:
如果是更新语句,尽量以主键为条件,唯一约束也可以,因为主键和唯一约束都只会把更新的那一行加X锁。再不济,也要是以普通索引去更新。
大忌:以非索引字段去更新,这样会导致所有的列都加X锁,此时所有的 insert/update 都无法操作。
验证(count已经改为非索引):
可以看到,阻塞住了。
查询INNODB_LOCKS:
supremum pseudo-record:表示无穷大
分布式事务也是面试的一个高频知识点。1. 事务基本概念1.1 什么是事务?事务是恢复和并发控制的基本单位,事务有四个特性(ACID),原子性(Atomicity),一致性(Consistency),隔...
2024.11.15前言最近老顾经常碰到同事说,mysql又死锁了导致业务报错。今天我们就来聊聊死锁以及怎么解决锁类型mysql锁级别:页级、表级、行级表级锁:开销小,加锁快;不会出现死锁;锁定粒度大,发生锁冲突的概率最...
2024.11.15快照读与当前读在RR级别下,通过MVCC机制,可以实现可重复读,但是读到的数据是历史数据,不是数据库最新数据。这种读取历史数据的方式叫快照读,而读取数据库最新版本数据的方式叫当前读。快照读当执行sel...
2024.11.15首先数据库技术发展的基础还是在业务推动的背景下,能够实现相关的技术保障。业务需求的提升必然会在数据量,访问量等方面有更高的要求,而映射到数据库层面就不是简单的扩容和添加资源了,我们有时候更需要弹性,...
2024.11.15在上一篇文章最后,我给你留了一个关于加锁规则的问题。今天,我们就从这个问题说起吧。为了便于说明问题,这一篇文章,我们就先使用一个小一点儿的表。建表和初始化语句如下(为了便于本期的例子说明,我把上篇文章...
2024.11.15