vlambda博客
学习文章列表

mysql 8.0 学习笔记07 锁和事务

概念介绍:

事务:

ACID 特性

原子性(Atomicity)

原子性是指事务包含的所有操作要么全部成功,要么全部失败回滚

一致性(Consistency)

事务只能以允许的方式改变其受影响的数据

隔离性(Isolation)

并发事务,不能导致数据库处于不一致的状态。

持久性(Durability)

无论数据库和系统是否发生故障,数据都会永久保留在磁盘上,并且不会丢失

只有innodb支持事务。

隔离级别:

事务隔离级别(只说常用的两种)

默认配置

Read-Committed

不可重复读

oracle、pg、sqlserver 等

Repeatable-Read

可重复读

mysql默认

脏读

读到其他事务未提交的数据;

不可重复读

针对数据修改Update造成的不一致,称为不可重复读

幻读

针对数据插入和删除等造成的不一致

锁:


mysql 8.0 学习笔记07 锁和事务


innodb 行锁是通过给索引项加锁实现的。

如果没有索引,会通过隐藏的聚簇索引来对记录加锁。

如果不通过索引条件检索数据,那么innodb将对表中所有的数据加锁,实际效果跟表锁一样。

索引加锁过程:

首先对二级索引加锁,然后还需要关联到主键索引,进行加锁。

锁队列:

当排它锁在队列中时,所有后续的共享锁也将被阻塞并保留在队列中。

锁的兼容性:

  • 意向锁之间,完全兼容;

  • S锁之间,互相兼容。

  • X锁,相互排斥、完全排斥。

特别说明:flush table with read lock;

等待表中所有操作完成,也将阻止该表上的所有操作。

为了备份一致性,所有备份方法都使用flush tables with read lock;然而,如果表上存在长时间运行的事务,这种做法可能会带来危险。

  • MVCC——简称multiversion concurrency control,也就是多版本并发控制,是个很基本的概念。MVCC的作用是让事务在并行发生时,在一定隔离级别前提下,可以保证在某个事务中能实现一致性读,也就是该事务启动时根据某个条件读取到的数据,直到事务结束时,再次执行相同条件,还是读到同一份数据,不会发生变化(不会看到被其他并行事务修改的数据);

  • read view——InnoDB MVCC使用的内部快照的意思。在不同的隔离级别下,事务启动时(有些情况下,可能是SQL语句开始时)看到的数据快照版本可能也不同。在上面介绍的几个隔离级别下会用到 read view;

  • 快照读——就是所谓的根据read view去获取信息和数据,不会加任何的锁;

  • 当前读——前读会获取得到所有已经提交数据,按照逻辑上来讲的话,在一个事务中第一次当前读和第二次当前读的中间有新的事务进行DML操作,这个时候俩次当前读的结果应该是不一致的,但是实际的情况却是在当前读的这个事务还没提交之前,所有针对当前读的数据修改和插入都会被阻塞,主要是因为next-key lock解决了当前读可能会发生幻读的情况。next-key lock当使用主键索引进行当前读的时候,会降级为record lock(行锁)。

innodb 为实现MVCC,UNDO 回滚,所有行 增加了三个内部属性列

  • DB_TRX_ID: 记录每行最近修改它的事务ID;

  • DB_ROLL_PTR: 指向回滚段UNDO日志的指针;

  • DB_ROW_ID: 写入数据时,自动维护的自增列。



READ COMMITTED和REPEATABLE READ隔离级别是利用consistent read view(一致读视图)方式支持的。所谓的consistent read view就是在某一时刻给事务系统trx_sys打snapshot(快照),把当时的trx_sys状态(包括活跃读写事务数组)记下来,之后的所有读操作根据其事务ID(即trx_id)与snapshot中trx_sys的状态做比较,以此判断read view对事务的可见性。

REPEATABLE READ隔离级别(除了GAP锁之外)和READ COMMITTED隔离级别的差别是创建snapshot时机不同。

REPEATABLE READ隔离级别是在事务开始时刻,确切的说是第一个读操作创建read view的时候,READ COMMITTED隔离级别是在语句开始时刻创建read view的。

因此:REPEATABLE READ隔离级别下面一个事务的SELECT操作只会获取一个read view,但是READ COMMITTED隔离级别下一个事务是可以获取多个read view的。