ACID 中的一致性(Consistency)
ACID 是事务的四大特性(原子性 Atomicity、一致性 Consistency、隔离性 Isolation、持久性 Durability),其中一致性 是核心目标,也是区别于其他三个 "手段性特性" 的关键 ------ 原子性、隔离性、持久性都是为了保证事务执行前后,数据库始终处于符合业务规则和数据约束的合法状态 **。
核心定义
事务执行的结果,必须使数据库从一个一致性状态 转变为另一个一致性状态 ,中间不会出现违反约束、规则、逻辑的 "中间非法状态"。简单说:数据的变化必须符合所有预设的规则,这些规则是保障业务正确性的基础。
一致性的核心保障规则
数据库的一致性由数据库自身约束 和业务逻辑约束共同保障,缺一不可:
- 数据库内置约束 (由数据库自动校验,事务失败会回滚)
- 主键唯一性:主键值不能重复、非空
- 外键关联:外键值必须在主表中存在,不能引用不存在的数据
- 字段约束:数据类型、长度、非空、唯一索引、默认值等
- 触发器 / 存储过程:数据库层面定义的自动校验逻辑
- 业务逻辑约束 (由开发人员通过代码 / 事务设计实现)
- 金额守恒:比如转账时,A 账户扣钱和 B 账户加钱的金额必须相等,总金额不变
- 库存规则:下单时库存不能为负,扣减库存的数量不能大于现有库存
- 状态逻辑:订单状态不能从 "已完成" 直接变为 "待付款",需符合业务流转规则
经典案例:转账事务的一致性体现
假设 A 账户有 1000 元,B 账户有 500 元,A 向 B 转账 200 元,事务的核心操作是:
sql
BEGIN; -- 开启事务
UPDATE account SET balance = 800 WHERE id = A; -- A扣200
UPDATE account SET balance = 700 WHERE id = B; -- B加200
COMMIT; -- 提交事务
- 执行前一致性:总金额 1500 元,各账户余额合法;
- 执行中 :若仅执行第一步(A 扣 200),事务未提交时总金额变为 1300 元,属于中间非法状态 ,但此时其他事务无法看到该状态(由隔离性保障);
- 执行后一致性:总金额仍为 1500 元,A、B 余额合法,符合业务规则;
- 若执行失败 :比如 B 账户不存在,由原子性保障事务回滚,恢复到执行前的一致性状态。
一致性与其他 ACID 特性的关系
原子性、隔离性、持久性是实现一致性的手段,一致性是最终目标,四者相互依赖:
- 原子性 → 保障一致性:事务要么全做,要么全不做,避免出现 "做了一半" 的非法状态;
- 隔离性 → 保障一致性:多个并发事务之间相互隔离,避免彼此的中间状态互相干扰,导致数据混乱;
- 持久性 → 保障一致性:事务提交后,数据修改永久生效,不会因系统故障丢失,确保最终状态的一致性。
容易混淆的点:"一致性"≠"强一致性"
ACID 的一致性是事务层面的逻辑一致性 ,而分布式系统中的 "强一致性"(如 CAP 中的 C)是数据副本之间的状态一致性,二者概念不同:
- ACID 一致性:关注单数据库中事务执行前后,数据符合业务 / 约束规则;
- 分布式强一致性:关注多数据库副本之间,数据状态实时保持一致。
一致性被破坏的常见场景
- 事务未遵循原子性:执行一半手动中断,或未捕获异常导致部分操作执行;
- 并发事务未做隔离:比如脏读、不可重复读、幻读,导致多个事务互相干扰;
- 忽略业务逻辑约束:比如未校验库存就扣减,导致库存为负;
- 数据库约束未生效:比如未设置外键、唯一索引,导致数据重复 / 无效。
如何保障业务中的一致性?
- 利用数据库内置约束:合理设置主键、外键、唯一索引、非空约束等,让数据库自动校验;
- 保证事务的原子性:所有相关操作放在同一个事务中,捕获异常并主动回滚;
- 设置合适的隔离级别:根据业务需求选择读已提交、可重复读(MySQL 默认)、串行化等隔离级别,避免并发干扰;
- 完善业务代码校验:在执行数据库操作前,先校验业务规则(如库存、金额、状态),提前拦截非法操作;
- 分布式场景补充:若为分布式系统,可通过 2PC、TCC、SAGA 等分布式事务方案,保障跨库 / 跨服务的一致性。
ACID 四大特性对比表
| 特性 | 英文 | 核心定义 | 核心目标 | 实现手段 / 关键机制 | 典型保障场景 | 缺失后的问题 |
|---|---|---|---|---|---|---|
| 原子性 | Atomicity | 事务是不可分割的最小执行单元,要么全部执行成功,要么全部回滚,无中间状态 | 避免 "部分执行" 的非法数据状态 | 1. 数据库事务日志(undo log)2. 异常捕获与主动回滚3. 操作原子化封装 | 转账时 A 扣钱、B 加钱要么都成,要么都败 | 数据出现 "半拉子操作",如 A 扣钱后 B 未加钱 |
| 一致性 | Consistency | 事务执行前后,数据库从一个合法一致性状态 转为另一个合法状态,符合所有约束 / 业务规则 | 保障数据逻辑与业务规则的正确性(ACID 核心目标) | 1. 数据库内置约束(主键 / 外键 / 字段约束)2. 业务代码前置校验3. 原子性 + 隔离性 + 持久性的协同保障 | 转账总金额守恒、库存不为负、订单状态流转合法 | 数据违反规则,如库存为负、金额不匹配 |
| 隔离性 | Isolation | 多个并发执行的事务之间相互独立、互不干扰,每个事务看不到其他事务的中间状态 | 避免并发事务互相干扰导致数据混乱 | 1. 数据库隔离级别(读未提交 / 读已提交 / 可重复读 / 串行化)2. 锁机制(行锁 / 表锁 / 间隙锁)3. MVCC(多版本并发控制) | 多用户同时下单、转账时数据不混乱 | 出现脏读、不可重复读、幻读,数据结果错误 |
| 持久性 | Durability | 事务提交后,对数据库的所有修改永久生效,即使发生系统崩溃、断电等故障也不会丢失 | 保障已提交数据的永久有效性 | 1. 数据库事务日志(redo log)2. 数据刷盘机制(内存数据持久化到磁盘)3. 主从复制 / 数据备份 | 提交订单后,即使服务器重启,订单数据仍存在 | 事务提交后数据丢失,业务结果不可信 |
补充核心关联
四者为手段 + 目标 的协同关系:原子性、隔离性、持久性是实现一致性的三大核心手段,一致性是 ACID 的最终核心目标,缺一不可。