5-事务
事务:由一组操作构成的可靠的独立的工作单元。具备 ACID 特性,即原子性,一致性,隔离性,持久性。
- 原子性 Atomicity: 事务中的所有操作要么全部成功,要么全部失败。只要有一项失败,整个事务的所有操作全部回滚。
- 一致性 Consistency: 事务的执行不能破坏数据库的完整性和一致性,事务在执行之前和之后,数据库都必须处于一致性状态。
- 隔离性 Isolation:(读未提交,读已提交,可重复读,可串行化) 在并发环境中,并发的事务是相互隔离的,一个事务的执行不能被其他事务干扰。即不同的事务并发操作相同的数据时,并发执行的各个事务之间不能相互干扰。
- 持久性 Durability: 一个事务一旦提交,它对数据库中对应数据的状态变更就应该是永久性的,要求遇到机器宕机、系统崩溃等意外发生后,依然能恢复到事务成功结束时的状态。
InnoDB 通过 日志和锁 来保证事务的 ACID 特性,具体如下:
- 通过 Redo Log 来保障事务的 持久性
- 通过 Undo Log 来保障事务的 原子性
- 通过 MVCC 或 锁来保证事务的 隔离性
- 通过
持久性+一致性+隔离性
来保证 一致性
并行事务会引发的问题¶
-
脏读 Dirty Read: 事务 A 读到了事务 B 还未提交的数据。
-
幻读 Phantom Read: 事务 A 在读某个范围,事务 B 新增或删除了满足该范围的记录,当 A 再次进行查询的时候发现多了或少了。
-
不可重复读 Non-Repeatable Read: 事务 A 读取某些数据后,再次读取该数据发现与上次不同,因为事务 B 对其进行了变更或删除。
幻读和不可重复读的区别¶
...
Note
对于上述问题,SQL 标准提出了四种隔离级别来规避这些问题,分别是: 读未提交、读提交、可重复度、串行化。
- 读未提交 Read Uncommitted: 指一个事务还没提交时,它做的变更就已经能被其他事务读到。
- 读提交 Read Committed: 指一个事务提交以后,它做的变更才能被其他事务读到。
- 可重复读 Repeatable Read: 指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的。
- 串行化 Serializable: 对记录加上读写锁,当多个事务对这条记录进行读写操作时,如果发生读写冲突,后访问的事务必须等前一个事务执行完成才能继续。
按隔离水平高低排序如下:
串行化 > 可重复读 > 读提交 > 读未提交
不同的隔离级别会导致不同的问题,如下表所示:
读未提交 | 读已提交 | 可重复读 | 串行化 |
---|---|---|---|
幻读 | 幻读 | 幻读 | |
不可重复读 | 不可重复读 | ||
脏读 |
Redo Log 如何保障持久性? 具体方式为:Redo Log 记录的是新数据的备份。在事务提交前,先持久化 Redo log,再更新到数据库中。即使发生故障,系统恢复后也可以通过 Redo Log 将数据恢复回去。
Undo Log 如何保障原子性? 具体方式为:Undo Log 记录数据在修改前的样子,然后再进行修改。如果出现错误或者执行 Rollback 语句,则可以利用 Undo Log 的备份数据将数据恢复回去。
脏读:事务 A 读到了事务 B 还未提交的数据。 幻读:事务 A 在读某个范围,事务 B 新增或删除了满足该范围的记录,当 A 再次进行查询的时候发现多了或少了。 不可重复读:事务 A 读取某些数据后,再次读取该数据发现与上次不同,因为事务 B 对其进行了变更或删除。
幻读和不可重复度的区别: 幻读:在同一事务中,相同条件下,两次查询出来的 记录数 不一样; 不可重复读:在同一事务中,相同条件下,两次查询出来的 数据 不一样;