提纲:
🔥事务 & 锁 & 日志
事务 ACID
InnoDB 引擎对 ACID 的实现
并发问题与解决
🎈面试八股真题——在【Java八股-第二十八期】优化 中总结
一、事务 & 锁 & 日志
1. 事务 ACID
-
1、Atomic 原子性:事务中所有 sql 语句是一个不可拆分的整体,要么同时失败,要么同时成功
-
2、Consistency 一致性:事务前后数据总量不变,例如转账
-
3、Isolation 隔离性:由存储引擎的事务隔离级别决定
-
4、Durable 持久性:事务对数据的修改会持久化存储到磁盘
2.InnoDB 引擎对 ACID 的实现
-
1、原子性:通过 undo-log 来实现数据的回滚
-
# InnoDB 中,事务每执行一条增删改语句,就将修改后的数据版本存储在 undo-log 版本链中,版本主要信息有数据的主键 ID/事务的 ID/回滚指针,当需要进行回滚时,就会根据回滚指针找到事务开始前的数据版本进行回滚
-
-
2、持久性:通过 redo-log 来实现
-
#InnoDB 中,对数据的修改是在 InnoDB 缓存中修改的,修改后的数据会在 MySQL 空闲时由后台线程刷入磁盘,在这期间,这部分数据就是脏数据,InnoDB 引擎通过在执行修改后,将数据拷贝至 redo-log buffer 中,并默认每隔 1 秒刷入磁盘,并在事务提交时,在将 bin-log 刷入磁盘后,为 redo-log 中的数据添加 commit 标记,记录事务成功提交,当 MySQL 宕机导致缓存中的脏数据丢失时,就可以通过 redo-log 进行数据恢复,保证事务的持久性
-
-
3、隔离性:见下文
-
4、一致性:当前原子性与隔离性保证时,一致性自然保证
3.并发问题与解决
-
并发问题
-
1、数据更新丢失,当并发事务指令交错时,就可能造成 A 对数据的修改被 B 覆盖
-
2、脏读,事务 A 读取了事务 B 修改后还未提交的数据,并在这个数据上进行事务,然而事务B 最后执行失败进行了回滚,可能导致数据总量前后不一致等问题
-
3、不可重复读,比如有一个事务 A,选择一条数据进行修改,并且修改的条件是性别为男,A 读取了数据后,判断为男性,此时 B 事务将性别修改为女并提交,在 A 进行修改时,就会发现数据前后不一致,从而修改失败
-
4、幻读,幻读与不可重复读的区别在于,不可重复读主要由于数据前后不一致,幻读主要由于数据前后的存在性不一致,例如有事务 A 要添加一条数据,添加前先根据主键进行判断,判断不存在后,还没有来的及添加,事务 B 此时将这条数据加入了表并提交,导致事务 A 添加失败
-
-
隔离级别
-
1、读已提交
-
2、可重复读
-
3、串行化
-
-
InnoDB 的实现
-
MVCC
-
对于 Select 操作,InnoDB 默认使用 MVCC 的不加锁的思想,来实现读已提交和可重复读的隔离级别
-
原理
-
-