隔离级别

串行化: 事务中对数据上读锁、写锁、范围锁

可重复读:上读锁、写锁直到事务结束,但是不加范围锁; 导致幻读问题: 两个完全相同的范围查到了不同的结果 - Mysql 默认的级别

读已提交: 上写锁直到事务结束,加读锁之后会立即释放; 上读锁前,需要等待写锁释放掉,即等待另一个事务提交完成,但是当读锁被释放了,另一个事务上写锁的时候,就不需要等待这个事务的读锁了,所以另一个事务可以成功修改数据造成了 同一行数据,两个查询,结果不同,是另一个已经提交的事务造成的 - 不可重复读问题

读未提交:上写锁直到事务结束,但是不加读锁; 意味着另一个事务不需要提交,都可以直接修改数据 - 脏读

上述的读写锁都是2PL的思想,即悲观并发控制,等待时间增加,可能会死锁,性能会下降

2PL:两段式加锁 - 注意和2PC区分 , 类似于读写锁 , 写必须等到读结束,读必须等到写释放。

Mysql 查询默认的隔离级别:

查看系统隔离级别:select @@global.tx_isolation;
查看会话隔离级别(5.0以上版本):select @@tx_isolation;
查看会话隔离级别(8.0以上版本):select @@transaction_isolation;

MVCC

因为数据库的事务时间是没有限制的,并且事务存在嵌套的特征,导致2PL性能非常的不稳定。

基于MVCC的数据版本号控制,在读取的时候不加锁,如果涉及到写:

  • 可重复读级别: 获取版本小于等于当前事务ID的记录
  • 读已提交:取最新的版本的数据

MVCC是基于快照提交事务,乐观并发控制,即直到提交的时候,如果监测到冲突就直接回退。 那么如何监测到存在写的冲突呢? SSI - 序列化快照隔离: 当事务提交的时候,必须要在索引中查找最近曾读取受影响数据的其他事务,告知他们这个数据我这里已经提交了,等你们需要提交的时候必须中止

乐观锁(Optimistic Lock)

MVCC 和 2PL的区别: 快照隔离读不阻塞写,写也不阻塞读。

这种设计原则下,查询延迟更可以预测了

  • 复习 数据库并发控制 (@2024-01-18)