Skip to content

5-事务

事务:由一组操作构成的可靠的独立的工作单元。具备 ACID 特性,即原子性,一致性隔离性持久性

  1. 原子性 Atomicity: 事务中的所有操作要么全部成功,要么全部失败。只要有一项失败,整个事务的所有操作全部回滚。
  2. 一致性 Consistency: 事务的执行不能破坏数据库的完整性和一致性,事务在执行之前和之后,数据库都必须处于一致性状态。
  3. 隔离性 Isolation:(读未提交,读已提交,可重复读,可串行化) 在并发环境中,并发的事务是相互隔离的,一个事务的执行不能被其他事务干扰。即不同的事务并发操作相同的数据时,并发执行的各个事务之间不能相互干扰。
  4. 持久性 Durability: 一个事务一旦提交,它对数据库中对应数据的状态变更就应该是永久性的,要求遇到机器宕机、系统崩溃等意外发生后,依然能恢复到事务成功结束时的状态。

InnoDB 通过 日志和锁 来保证事务的 ACID 特性,具体如下:

  1. 通过 Redo Log 来保障事务的 持久性
  2. 通过 Undo Log 来保障事务的 原子性
  3. 通过 MVCC 或 锁来保证事务的 隔离性
  4. 通过持久性+一致性+隔离性来保证 一致性

并行事务会引发的问题

  1. 脏读 Dirty Read: 事务 A 读到了事务 B 还未提交的数据。

  2. 幻读 Phantom Read: 事务 A 在读某个范围,事务 B 新增或删除了满足该范围的记录,当 A 再次进行查询的时候发现多了或少了。

  3. 不可重复读 Non-Repeatable Read: 事务 A 读取某些数据后,再次读取该数据发现与上次不同,因为事务 B 对其进行了变更或删除。

幻读和不可重复读的区别

...

Note

对于上述问题,SQL 标准提出了四种隔离级别来规避这些问题,分别是: 读未提交、读提交、可重复度、串行化

  1. 读未提交 Read Uncommitted: 指一个事务还没提交时,它做的变更就已经能被其他事务读到。
  2. 读提交 Read Committed: 指一个事务提交以后,它做的变更才能被其他事务读到。
  3. 可重复读 Repeatable Read: 指一个事务执行过程中看到的数据,一直跟这个事务启动时看到的数据是一致的。
  4. 串行化 Serializable: 对记录加上读写锁,当多个事务对这条记录进行读写操作时,如果发生读写冲突,后访问的事务必须等前一个事务执行完成才能继续。

按隔离水平高低排序如下:

串行化 > 可重复读 > 读提交 > 读未提交

不同的隔离级别会导致不同的问题,如下表所示:

读未提交 读已提交 可重复读 串行化
幻读 幻读 幻读
不可重复读 不可重复读
脏读

Redo Log 如何保障持久性? 具体方式为:Redo Log 记录的是新数据的备份。在事务提交前,先持久化 Redo log,再更新到数据库中。即使发生故障,系统恢复后也可以通过 Redo Log 将数据恢复回去。

Undo Log 如何保障原子性? 具体方式为:Undo Log 记录数据在修改前的样子,然后再进行修改。如果出现错误或者执行 Rollback 语句,则可以利用 Undo Log 的备份数据将数据恢复回去。

脏读:事务 A 读到了事务 B 还未提交的数据。 幻读:事务 A 在读某个范围,事务 B 新增或删除了满足该范围的记录,当 A 再次进行查询的时候发现多了或少了。 不可重复读:事务 A 读取某些数据后,再次读取该数据发现与上次不同,因为事务 B 对其进行了变更或删除。

幻读和不可重复度的区别: 幻读:在同一事务中,相同条件下,两次查询出来的 记录数 不一样; 不可重复读:在同一事务中,相同条件下,两次查询出来的 数据 不一样;