数据库的 ACID 属性是指原子性(Atomicity)、一致性(Consistency)、隔离性(Isolation)和持久性(Durability),是确保数据库事务处理正确、可靠的关键特性,以下是具体介绍:
原子性(Atomicity)
- 含义:事务中的操作要么全部成功执行,要么全部不执行,就像一个不可分割的原子。比如银行转账,从账户 A 转 100 元到账户 B,这包含从 A 账户扣款和向 B 账户加款两个操作,要么都完成,要么都不做,不会出现 A 账户扣了钱而 B 账户没加钱的情况。
- 实现方式:通过日志和回滚机制实现,数据库会记录事务操作前的状态,若事务执行中出错,就根据日志将数据回滚到事务开始前的状态。
一致性(Consistency)
- 含义:事务执行前后,数据库从一个合法的状态转换到另一个合法状态,数据的完整性约束等得到满足。如转账前后,A、B 账户余额总和应保持不变,不能出现转账后总金额增加或减少的情况。
- 实现方式:靠数据库的约束、规则以及应用程序的逻辑来保证,数据库要检查数据是否符合定义的约束条件,应用程序也要确保业务逻辑正确。
隔离性(Isolation)
- 含义:多个并发事务之间相互隔离,一个事务的执行不能被其他事务干扰,每个事务感觉不到其他事务在并发执行。例如多个用户同时转账,每个用户的转账事务应相互隔离,不会出现数据混乱。
- 实现方式:通过锁机制和并发控制技术实现,数据库会根据事务隔离级别,对数据加不同类型的锁,防止并发事务之间的干扰。
持久性(Durability)
- 含义:事务一旦提交,其对数据库的修改就会永久保存,即使数据库系统崩溃或出现其他故障,数据也不会丢失。如转账成功后,即使数据库服务器突然断电,转账记录也会被保存下来。
- 实现方式:利用日志文件和数据备份来实现,事务提交时,先将事务日志写入磁盘,确保数据已持久化,还会定期进行数据备份,以便在故障后恢复数据。
举例说明一致性和和隔离性
一致性
假设银行数据库中有一个账户表,表中记录了每个用户的账户余额等信息,并规定账户余额不能为负数。
用户 A 的账户原本有 1000 元余额,他发起了一笔购买 500 元商品的交易。这个交易在数据库中对应的事务应该包括从 A 的账户余额中减去 500 元的操作。在事务执行前,数据库中的数据是符合一致性要求的,账户余额为正且符合实际情况。
- 如果事务正常执行,从 A 的账户余额中成功减去 500 元,数据库中的数据依然保持一致性,A 的账户余额变为 500 元,没有违反任何约束条件。
- 但如果事务执行过程中出现错误,比如系统突然崩溃,导致只执行了扣除操作的一部分,使得 A 的账户余额变为了一个错误的值,或者变成了负数,那么数据库就处于不一致的状态,破坏了数据的完整性和业务规则。
隔离性
假设有两个用户 A 和 B 同时对同一个账户进行操作,账户初始余额为 1000 元。
用户 A 发起一个取款 500 元的事务,用户 B 发起一个查询账户余额的事务。
- 若隔离性未保证:可能会出现这样的情况,用户 A 的取款事务还未完全提交,正在执行从账户余额中减去 500 元的操作时,用户 B 的查询事务就获取到了数据,此时 B 查询到的余额可能是扣除 500 元过程中的中间状态,比如余额显示为 500 元,但实际上 A 的取款事务还没完成,这就导致了数据的不一致和混乱,用户 B 得到了一个不准确的结果。
- 若隔离性保证:根据不同的隔离级别,数据库会采取相应措施。比如在可重复读隔离级别下,用户 B 的查询事务会在用户 A 的取款事务提交完成后才执行,或者在用户 A 事务执行过程中,用户 B 查询到的依然是账户初始的 1000 元余额,直到用户 A 的事务提交后,用户 B 再次查询才会得到更新后的 500 元余额,这样就保证了每个事务的执行不受其他事务的干扰,结果是符合预期和正确的。