ACID

Sun Jun 29 2025 · 5min

ACID 是数据库事务(Transaction)的四个核心属性的缩写:原子性 (Atomicity)、一致性 (Consistency)、隔离性 (Isolation) 和持久性 (Durability)。这些属性共同确保了数据库事务的可靠性、完整性和正确性,尤其在金融、电商等对数据准确性要求极高的场景中至关重要。

让我们用一个经典的例子来理解这四个概念:银行转账。假设你要从 A 账户转 100 元到 B 账户。这个操作包括两个步骤:

  1. 从 A 账户扣除 100 元。
  2. 给 B 账户增加 100 元。

A: 原子性 (Atomicity) - “全有或全无”

理解: 原子性是指一个事务要么完全执行成功,要么完全不执行(回滚)。它是一个不可分割的最小工作单元。在上述转账例子中,如果从 A 账户扣除了 100 元,但因为系统故障或其他原因未能成功给 B 账户增加 100 元,那么整个转账操作必须被撤销,A 账户的钱必须恢复原样。决不能出现 A 账户少了钱而 B 账户没收到钱的中间状态。

作用: 防止数据处于部分完成的、不确定的状态,确保数据的完整性。


C: 一致性 (Consistency) - “从一个有效状态到另一个有效状态”

理解: 一致性是指事务必须使数据库从一个一致的状态转换到另一个一致的状态。这意味着事务完成后,数据库必须遵守所有的预定义规则、约束(如唯一性约束、外键约束)、触发器等。在转账例子中,假设银行规定所有账户的余额总和必须保持不变。如果 A 账户扣除 100 元,B 账户增加 100 元,那么总金额不变,数据库处于一致状态。如果转账失败(原子性保证回滚),总金额也回到一致状态。

作用: 保证数据的有效性和完整性,避免产生无效或矛盾的数据。


I: 隔离性 (Isolation) - “互不干扰”

理解: 隔离性是指多个并发执行的事务之间互不干扰。当多个事务同时操作相同的数据时,每个事务都感觉自己是唯一在操作数据库的。一个事务的中间状态对其他事务是不可见的。在转账例子中,假设你在从 A 账户转账给 B 账户的同时,另一个人也在查询 A 账户的余额。隔离性保证这个人要么看到转账前的 A 账户余额,要么看到转账完成后的 A 账户余额,而不会看到 A 账户钱已经被扣除但 B 账户还没增加的中间状态。

作用: 避免并发操作导致的数据异常,如脏读(读取了未提交的数据)、不可重复读(在同一事务内多次读取同一数据,结果不同)、幻读(在同一事务内多次查询,发现新的符合条件的记录)。隔离级别越高,数据一致性越好,但并发性能可能越差。


D: 持久性 (Durability) - “一旦提交,永久有效”

理解: 持久性是指一旦事务被成功提交 (Committed),它对数据库的修改就是永久性的,即使系统发生故障(如电源故障、系统崩溃)也不会丢失。在转账例子中,一旦 A 账户的钱被扣除,B 账户的钱被增加,并且银行系统确认“转账成功”(事务提交),即使服务器立即断电,这些修改也必须被永久保存下来,当系统恢复后,数据仍然是正确的。通常通过将事务日志写入磁盘来实现持久性。

作用: 确保已提交的数据不会丢失,保证数据的可靠性。


为什么 ACID 很重要?

ACID 属性是关系型数据库的基石,它们共同提供了数据处理的可靠保障。如果没有 ACID 特性,数据库在面对并发操作、系统故障时,就可能出现数据损坏、丢失或不一致的情况,这将是灾难性的。

虽然现代的 NoSQL 数据库为了追求高可用性和可伸缩性,往往会放宽对 ACID 特性(特别是隔离性和一致性)的严格要求,转而采用 BASE (Basically Available, Soft state, Eventually consistent) 模型,但这通常是有意为之的权衡,适用于对最终一致性可以接受的场景。在需要强事务保证和数据严格一致性的业务场景中,ACID 仍然是首选。