数据库的事务

警告
本文最后更新于 2023-02-27,文中内容可能已过时。

数据库事务的四大特性,也称为ACID特性,分别是原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。

  • 原子性(Atomicity):原子性说明事务在执行时必须作为一个原子操作进行:要么全部成功,要么全部失败。
  • 一致性(Consistency):一致性表示事务启动前和启动后,数据库中受事务影响的数据都处于一致状态。
  • 隔离性(Isolation):隔离表示事务之间不会相互影响,它们可以并行执行,而无需等待其他事务的完成,也不需要同步数据。
  • 持久性(Durability):持久性表示一旦事务执行完毕,其结果就在数据库中持久保存,即使发生系统崩溃。

数据库隔离性是一组规则,用于防止由多个并发会话对数据库中潜在共享数据造成不一致性。 它还可以确保避免数据意外更新和多重状态。

隔离级别定义了同一个会话执行关系操作之间的并发性。 级别较低时,可能会出现数据安全和一致性问题; 较高时,并发性可能会有所降低,但并发操作之间的数据一致性会得到更好的保障。常见的隔离级别如下:

  • READ UNCOMMITTED :一个事务内看到其他未提交的事务修改。
  • READ COMMITTED :一个事务内只能看到其他已提交事务修改。
  • REPEATABLE READ:一个事务内只能读取其他已提交的事务修改,且读取的数据对其他会话是只读的。
  • SERIALIZABLE :一个事务内只能读取其他已提交的事务修改,且读取的数据不能共享给其他会话。

假如现在启动两个事务 A 和 B,执行顺序为下表的中状态:

事务A 事务B
启动事务查询得到值1 启动事务
查询得到值1
将1改成2
拆线呢得到值 V1
提交事务B
查询得到值 V2
提交事务A
查询得到值 V3

以下是不同隔离级别V1、V2、V3的结果

https://image.linux88.com/2023/02/27/cce2c562d2f54dde6d01d6a29aa8e25d.png

https://image.linux88.com/2023/02/27/5ed33afac371f60bcc1c697f4dec9ab8.png

当同一查询在不同时间产生不同集合的行时。例如,如果执行了两次SELECT,但第二次返回的行第一次没有返回,则该行是一个“幻读”行。

创建下面的表并插入数据。

1
2
3
4
5
6
7
8
9
CREATE TABLE `t` (
	`id` int(11) NOT NULL,
	`c` int(11) DEFAULT NULL,
	`d` int(11) DEFAULT NULL,
	PRIMARY KEY (`id`),
	KEY `c` (`c`)
) ENGINE = InnoDB;

INSERT INTO t VALUES (0, 0, 0), (5, 5, 5), (10, 10, 10), (15, 15, 15), (20, 20, 20), (25, 25, 25);

图中3次查询的结果都不一样,这违反了 REPEATABLE READ 事务的隔离原则,在事务期间不受更改。 https://image.linux88.com/2023/03/02/6c92457b162eef615b0479671f717143.png

为了防止出现幻读, InnoDB 使用了一种称为 next-key locking 的算法,该算法结合了 index-row 锁定和 gap 锁定。

  1. begin 或 start transaction,配套的提交语句是 commit,回滚语句是 rollback。begin/start transaction 命令并不是一个事务的起点,在执行到它们之后的第一个操作 InnoDB 表的语句,事务才真正启动(执行第一个快照读语句时创建一致性视图)。
  2. 一致性视图是在执行 start transaction with consistent snapshot 时创建的。
  3. set autocommit=0,这个命令会将这个线程的自动提交关掉。意味着如果你只执行一个 select 语句,这个事务就启动了,而且并不会自动提交。这个事务持续存在直到你主动执行 commit 或 rollback 语句,或者断开连接。

MySQL 实战 45 讲

Phantom Rows

相关内容