事务的 ACID 是指什么?

原子性(Atomic):事务中各项操作,要么全做要么全不做,任何一项操作

的失败都会导致整个事务的失败;

一致性(Consistent):事务结束后系统状态是一致的;

隔离性(Isolated):并发执行的事务彼此无法看到对方的中间状态;

持久性(Durable):事务完成后所做的改动都会被持久化,即使发生灾难

性的失败。通过日志和同步备份可以在故障发生后重建数据。

补充:关于事务,在面试中被问到的概率是很高的,可以问的问题也是很多的。

首先需要知道的是,只有存在并发数据访问时才需要事务。当多个事务访问同一

数据时,可能会存在 5 类问题,包括 3 类数据读取问题(脏读、不可重复读和幻

读)和 2 类数据更新问题(第 1 类丢失更新和第 2 类丢失更新)。

脏读(Dirty Read):A 事务读取 B 事务尚未提交的数据并在此基础上操作,而 B

事务执行回滚,那么 A 读取到的数据就是脏数据。

时间 转账事务 A

取款事务 B

T1

开始事务

T2

开始事务

T3

查询账户余额为 1000 元第 302 页 共 485 页

T4

取出 500 元余额修改为 500

T5

查询账户余额为 500 元(脏读)

T6

撤销事务余额恢复为 1000 元

T7

汇入 100 元把余额修改为 600

T8

提交事务

不可重复读(Unrepeatable Read):事务 A 重新读取前面读取过的数据,发现

该数据已经被另一个已提交的事务 B 修改过了。

时间 转账事务 A

取款事务 B

T1

开始事务

T2

开始事务

T3

查询账户余额为 1000 元

T4

查询账户余额为 1000 元

T5

取出 100 元修改余额为 900

T6

提交事务

T7

查询账户余额为 900 元(不可重复读)

幻读(Phantom Read):事务 A 重新执行一个查询,返回一系列符合查询条件

的行,发现其中插入了被事务 B 提交的行。第 303 页 共 485 页

时间 统计金额事务 A

转账事务 B

T1

开始事务

T2

开始事务

T3

统计总存款为 10000 元

T4

新增一个存款账户存入 100

T5

提交事务

T6

再次统计总存款为 10100 元(幻读)

第 1 类丢失更新:事务 A 撤销时,把已经提交的事务 B 的更新数据覆盖了。

时间 取款事务 A

转账事务 B

T1

开始事务

T2

开始事务

T3

查询账户余额为 1000 元

T4

查询账户余额为 1000 元

T5

汇入 100 元修改余额为 1100

T6

提交事务

T7

取出 100 元将余额修改为 900 元

T8

撤销事务

T9

余额恢复为 1000 元(丢失更新)第 304 页 共 485 页

第 2 类丢失更新:事务 A 覆盖事务 B 已经提交的数据,造成事务 B 所做的操作丢

失。

时间 转账事务 A

取款事务 B

T1

开始事务

T2

开始事务

T3

查询账户余额为 1000 元

T4

查询账户余额为 1000 元

T5

取出 100 元将余额修改为 900

T6

提交事务

T7

汇入 100 元将余额修改为 1100 元

T8

提交事务

T9

查询账户余额为 1100 元(丢失更新)

数据并发访问所产生的问题,在有些场景下可能是允许的,但是有些场景下可能

就是致命的,数据库通常会通过锁机制来解决数据并发访问问题,按锁定对象不

同可以分为表级锁和行级锁;按并发事务锁定关系可以分为共享锁和独占锁,具

体的内容大家可以自行查阅资料进行了解。

直接使用锁是非常麻烦的,为此数据库为用户提供了自动锁机制,只要用户指定

会话的事务隔离级别,数据库就会通过分析 SQL 语句然后为事务访问的资源加上

合适的锁,此外,数据库还会维护这些锁通过各种手段提高系统的性能,这些对

用户来说都是透明的(就是说你不用理解,事实上我确实也不知道)。ANSI/ISO

SQL 92 标准定义了 4 个等级的事务隔离级别,如下表所示:

隔离级别

脏读

不可重复读 幻读

第一类丢失更新 第二类丢失更新第 305 页 共 485 页

READ

UNCOMMITED

允许

允许

允许

不允许

允许

READ

COMMITTED

不允许 允许

允许

不允许

允许

REPEATABLE

READ

不允许 不允许

允许

不允许

不允许

SERIALIZABLE

不允许 不允许

不允许 不允许

不允许

需要说明的是,事务隔离级别和数据访问的并发性是对立的,事务隔离级别越高

并发性就越差。所以要根据具体的应用来确定合适的事务隔离级别,这个地方没

有万能的原则。

 

上一篇:Class test.Test3 can not access a member of class singleton.Single with modifiers “private“


下一篇:undo log在ACID中的作用