详解MySQL事务与锁

目录

事务相关概念

事务特点

InnoDB结构

事务并发的问题

脏读、不可重复读、幻读

事务的隔离级别

解决事务并发的方案

MVCC

InnoDB是怎么解决幻读的?


事务相关概念

事务特点

详解MySQL事务与锁_第1张图片

InnoDB结构

详解MySQL事务与锁_第2张图片

MySQL日志:bin log、undo log、redo log、relay log、error log、慢日志。

详解MySQL事务与锁_第3张图片

详解MySQL事务与锁_第4张图片

 

undo log 需要落盘

redo log(要落盘): 如图,

0:MySQL挂了,会丢数据

1: 不会丢,最安全,效率比较低。

2:MySQL挂了,系统没挂,不会丢

详解MySQL事务与锁_第5张图片

 

事务并发的问题

开启一个事务:begin;

事务结束:rollback、commit、工具自动回滚;

事务并发会带来什么问题?

脏读、不可重复读、幻读

问题1:事务B未提交,A读到的是脏数据,即脏读:读到其它事务未提交的数据。未提交的数据在内存缓冲池里面。

详解MySQL事务与锁_第6张图片

问题2:事务A读取到事务B已经提交的数据,即不可重复读

详解MySQL事务与锁_第7张图片

问题3:事务B插入了数据并提交,事务A读到了新的数据,即幻读insert才存在幻读

详解MySQL事务与锁_第8张图片

事务的隔离级别

上述三个问题都是读一致性的问题,必须由数据库提供一定的隔离机制来解决。提出了一个标准:SQL 92的标准。

详解MySQL事务与锁_第9张图片

 

未提交读:不用。

已提交读(RC):能够读取到其它事务已提交的数据,但不能读取其它事务未提交的数据,即解决脏读。

可重复读(RR):

串行化:一个一个排队进行,并发效率低。一般不用。

Oracle只有:RC、串行化。

MySQL实现如下:

详解MySQL事务与锁_第10张图片

解决事务并发的方案

如何保证一个事务前后两次读取的数据结果保持一致?事务隔离级别的解决方案:

详解MySQL事务与锁_第11张图片

MVCC

详解MySQL事务与锁_第12张图片

详解MySQL事务与锁_第13张图片

在Mysql中的锁可以分为分享锁/读锁(Shared Locks)排他锁/写锁(Exclusive Locks) 、间隙锁行锁(Record Locks)表锁

锁的粒度:

详解MySQL事务与锁_第14张图片

详解MySQL事务与锁_第15张图片

详解MySQL事务与锁_第16张图片

 

详解MySQL事务与锁_第17张图片

详解MySQL事务与锁_第18张图片

 

锁锁住的是索引。索引的本质:

1、表没有索引,为什么会锁表?

主键索引(primary key)、唯一索引(unique key)、row_id。

没有索引,自动创建row_id。依然会走全表扫描,这样会将隐藏的row_id都锁起来。

2、为什么将唯一索引锁住,主键索引也会被锁住?

因为回表

聚集索引(主键)

二级索引(联合索引、辅助索引)

详解MySQL事务与锁_第19张图片

InnoDB是怎么解决幻读的?

详解MySQL事务与锁_第20张图片

记录锁:锁定记录

详解MySQL事务与锁_第21张图片

间隙锁:锁定范围

详解MySQL事务与锁_第22张图片

 

临键锁:范围+记录

详解MySQL事务与锁_第23张图片

 

详解MySQL事务与锁_第24张图片

参考资料:

https://www.bilibili.com/video/BV13E411q7oV?t=5033

https://www.bilibili.com/video/BV1x54y1979n?t=48

https://www.jianshu.com/p/8845ddca3b23

https://juejin.im/post/6844903808376504327#heading-0

你可能感兴趣的:(#,MySQL)