数据库事务 ACID
数据库 ACID 是指数据库在执行事务(Transaction)时需要保证的四个特性,即原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability)。这些特性确保了数据库事务的可靠性,即使在系统故障或并发访问的情况下,也能维护数据的完整性。
一、原子性(Atomicity)
定义:事务中的所有操作要么全部完成,要么全部不完成,不可分割。如果事务执行过程中发生错误,系统会回滚(Rollback)到事务开始前的状态。
示例:
很通用的一个案例就是,假设一个银行转账事务包含两个操作:
1、从账户 A 扣除 100 元;
2、向账户 B 增加 100 元。
如果操作 2 失败,原子性要求操作 1 也必须撤销,确保账户 A 的钱不会凭空减少。
实现机制:
- 回滚日志(Undo Log):记录事务执行前的数据状态,用于回滚。
- 两阶段提交(2PC):分布式系统中确保跨节点事务的原子性。
二、一致性(Consistency)
定义:事务执行前后,数据库的状态必须满足所有业务规则和约束(如主键唯一、外键引用有效、数据类型合法等)。事务不能破坏数据库的完整性。
示例:继续 原子性 示例中的 转账 事务,无论操作是否成功,账户 A 和账户 B 的合计总金额必须保持不变(符合 "余额守恒" 规则)。
实现机制:
- 约束检查:数据库在执行事务时自动验证约束(如唯一约束、非空约束)。
- 触发器(Trigger):通过自定义逻辑维护数据一致性。
三、隔离性(Isolation)
定义:多个并发事务之间相互隔离,一个事务的执行不能被其他事务干扰。每个事务都要感觉自己是系统中唯一运行的事务。
示例:
当两个转账事务同时发生时,隔离性确保:
1、事务A不会看到事务B未提交的中间状态;
2、事务B必须等待事务A完成或回滚后才能访问相同数据。
实现机制:
- 锁(Lock):通过行锁、表锁限制并发访问。
- MVCC(多版本并发控制):为数据保存多个版本,允许事务读取历史版本,避免锁冲突。
事务的隔离级别(读未提交、读已提交、可重复读、串行化)决定了隔离的程度,详可见 数据库隔离级别。
四、持久性(Durability)
定义:一旦事务提交,其对数据库的修改将永久保存,即使系统崩溃或重启后数据也不会丢失。
示例:
转账事务提交后:
1、即使数据库服务器立即断电,重启后转账结果仍然存在。
2、系统会使用事务日志来恢复已提交但尚未写入数据文件的事务。
实现机制:
- 日志(Redo Log):事务修改先记录到日志文件(如 MySQL 的 Binlog、InnoDB 的 redo log),再异步刷新到磁盘。
- 预写日志(WAL, Write-Ahead Logging):确保事务提交前日志已写入磁盘。
- RAID、备份恢复:通过硬件冗余和定期备份进一步保障数据安全。
实际应用中的考虑
-
性能与 ACID 的权衡:更高的隔离级别通常意味着更低的并发性能。
-
分布式系统中的 ACID:在分布式环境下实现 ACID 更具挑战性,通常采用 BASE 理论作为补充。
-
NoSQL与ACID:许多NoSQL数据库牺牲部分ACID特性以获得更好的扩展性和性能。
ACID 与 BASE 的对比
- ACID:强一致性,适合对数据准确性要求极高的场景(如银行)。
- BASE(基本可用<Basically Available>、软状态<Soft state>、最终一致性<Eventually consistent>):弱一致性,适合互联网高并发场景(如电商库存的最终一致)。
为什么 ACID 很重要?
- 你想想,如果你的转账、支付、买奶茶的订单,总是出现脏读、幻读,那我们不是可以抓漏洞,使劲的薅羊毛了么,哈哈。
风雷雨露,天之灵;山川民物,地之灵;语言文字,人之灵。 -- 烟沙九洲