数据库事务是什么?数据库事务的 ACID 特性及使用详解

数据库事务是什么?数据库事务的 ACID 特性及使用详解
最新回答
仲夏柠叶香

2021-04-22 23:30:09

数据库事务是一系列不可分割的数据库操作,要么全部成功并永久保存,要么全部失败并回滚到事务开始前的状态,确保数据在复杂操作和并发环境下的完整性与一致性。

数据库事务的重要性
  • 数据一致性保障:确保数据库从一个有效状态转移到另一个有效状态,避免出现半成品数据。例如银行转账,不会出现钱从一个账户扣除却未到达另一个账户的情况。
  • 并发控制:在多用户同时访问数据库时,隔离不同用户的操作,避免互相干扰,防止脏读、不可重复读、幻读等问题。若两人同时修改同一条记录,事务隔离可避免结果混乱。
  • 故障恢复:系统崩溃或断电时,未完成的事务自动回滚,已提交的事务永久保存,使数据库具备强大的容错能力,防止数据损坏。

数据库事务的ACID特性
  • 原子性(Atomicity)

    一个事务中的所有操作,要么全部完成,要么全部不完成,是不可分割的工作单元。若事务中任一操作失败,整个事务回滚到开始前状态,已做修改被撤销。例如画画,要么画完所有细节,要么不画,不会只画一半。实现上通常通过日志(redo/undo log)保证,失败时利用undo log回滚。

  • 一致性(Consistency)

    事务执行前后,数据库从一个有效状态转换到另一个有效状态,不破坏数据库的完整性约束,如主键唯一性、外键引用完整性、check约束等。例如规定账户余额不能为负,转账事务不能导致任何账户余额变负,否则应回滚。这由业务逻辑和数据库约束共同保证。

  • 隔离性(Isolation)

    多个并发事务执行时,每个事务感觉自己是系统中唯一运行的事务,其执行不被其他并发事务干扰。一个事务提交前,所做修改对其他事务不可见。隔离级别有读未提交、读已提交、可重复读、串行化等,在性能和隔离程度间权衡。如读已提交隔离级别,事务只能看到其他事务已提交的数据,避免脏读,但完全避免并发问题会增加性能开销。

  • 持久性(Durability)

    一旦事务提交成功,对数据库的修改永久有效,即使系统故障(如断电、宕机)也不会丢失。通常将事务修改写入非易失性存储(如硬盘),数据写入磁盘前先写入预写日志(WAL,Write-Ahead Log),确保系统崩溃后能恢复数据。

实际开发中有效使用数据库事务的方法
  • 明确事务边界

    不是所有操作都需要事务,只有需“全部成功或全部失败”的逻辑单元才需要。如简单查询操作通常不需要,多表更新、跨越多个业务步骤的操作必须用事务。

  • 事务的开启、提交与回滚

    大多数关系型数据库提供明确语法控制事务:

    START TRANSACTION; 或 BEGIN;:开始一个事务。

    COMMIT;:提交事务,永久保存所有修改。

    ROLLBACK;:回滚事务,撤销所有修改。

    示例SQL:

-- 开启事务START TRANSACTION;-- 尝试从用户A的账户扣款100UPDATE accounts SET balance = balance - 100 WHERE user_id = 'A';-- 检查扣款是否成功,或者是否有足够余额-- 实际应用中,这里会有更复杂的业务逻辑和错误判断-- 假设扣款成功了,或者我们容忍负余额(不推荐)-- 尝试给用户B的账户加款100UPDATE accounts SET balance = balance + 100 WHERE user_id = 'B';-- 假设这里发生了某种错误,比如B用户不存在,或者网络中断-- 那么我们应该回滚事务-- IF error_occurred THEN-- ROLLBACK;-- ELSE-- COMMIT;-- END IF;-- 如果一切顺利,提交事务COMMIT;- 在应用程序代码中,如使用Java的JDBC、Python的SQLAlchemy等,通常有更高级的API管理事务,如设置`autoCommit(false)`,然后调用`connection.commit()`或`connection.rollback()`。
  • 注意事务的粒度

    事务不宜过长,长时间事务会占用数据库资源、持有锁,影响其他并发操作性能,甚至导致死锁。尽量让事务短小精悍,只包含必要逻辑。若业务流程复杂耗时,可拆分为多个小事务,或引入消息队列、补偿机制等保证最终一致性,而非依赖超长事务。

  • 重视异常处理

    在事务中,任何可能导致数据不一致的异常都应触发回滚。代码中需捕获异常,在适当时候调用ROLLBACK。同时考虑网络中断、数据库连接丢失等外部因素,健壮的系统会把事务成功与否视为业务流程关键环节,进行严密监控和日志记录。