数据库事务的ACID特性和隔离级别

jopen 10年前

1. 事务的四个特性

数据库事务(Transaction)是指作为单个逻辑工作单元执行的一系列操作,要么完全地执行,要么完全地不执行。一方面,当多个应用程序并发访问数据库时,事务可以在应用程序间提供一个隔离方法,防止互相干扰。另一方面,事务为数据库操作序列提供了一个从失败恢复正常的方法。

事务具有四个特性:原子性(Atomicity)、一致性(Consistency)、隔离型(Isolation)、持久性(Durability),简称ACID。

1.1 原子性(Atomicity)

事务的原子性是指事务中的操作不可拆分,只允许全部执行或者全部不执行。

1.2 一致性(Consistency)

事务的一致性是指事务的执行不能破坏数据库的一致性,一致性也称为完整性。一个事务在执行后,数据库必须从一个一致性状态转变为另一个一致性状态。

1.3 隔离型(Isolation)

事务的隔离型是指并发的事务相互隔离,不能互相干扰。

1.4 持久性(Durability)

事务的持久性是指事务一旦提交,对数据的状态变更应该被永久保存。

2 事务的四个隔离级别

实际工作中事务几乎都是并发的,完全做到互相之间不干扰会严重牺牲性能,为了平衡隔离型和性能,SQL92规范定义了四个事务隔离级别:读未提交(Read Uncommitted)、读已提交(Read Committed)、可重复读(Repeatable Read)、串行化(Serializable)。四个级别逐渐增强,每个级别解决上个级别的一个问题。

2.1 读未提交(Read Uncommitted)

另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据(脏读)。

脏读是指另一个事务修改了数据,但尚未提交,而本事务中的SELECT会读到这些未被提交的数据。

2.2 读已提交(Read Committed)

本事务读取到的是最新的数据(其他事务提交后的)。问题是,在同一个事务里,前后两次相同的SELECT会读到不同的结果(不可重复读)。

不可重复读是指同一个事务执行过程中,另外一个事务提交了新数据,因此本事务先后两次读到的数据结果会不一致。

2.3 可重复读(Repeatable Read)

在同一个事务里,SELECT的结果是事务开始时间点的状态,同样的SELECT操作读到的结果会是一致的。但是,会有幻读现象。

不可重复读保证了同一个事务里,查询的结果都是事务开始时的状态(一致性)。但是,如果另一个事务同时提交了新数据,本事务再更新时,就会发现了这些新数据,貌似之前读到的数据是幻觉,这就是幻读

2.4 串行化(Serializable)

所有事务只能一个接一个串行执行,不能并发。

3 隔离级别的选择

事务隔离级别越高,越能保证数据的一致性,但对并发性能影响越大,一致性和高性能必须有所取舍或折中。

一般情况下,多数应用程序可以选择将数据库的隔离级别设置为读已提交,这样可以避免脏读,也可以得到不错的并发性能。尽管这个隔离级别会导致不可重复度、幻读,但这种个别场合应用程序可以通过主动加锁进行并发控制。