什么是数据库的事务?

张开发
2026/4/13 21:35:01 15 分钟阅读

分享文章

什么是数据库的事务?
在之前的讨论中我们已经了解了脏读、不可重复读和幻读这些并发问题它们都源于多个事务同时执行时可能产生的数据不一致。要深入理解这些问题以及如何解决就需要先掌握数据库事务的核心概念。下面我会从事务的定义、ACID 属性、事务控制语句、隔离级别、实现机制以及实际应用这几个方面为你系统地介绍数据库事务。1. 什么是事务事务Transaction是数据库管理系统DBMS中执行的一组操作这些操作要么全部成功要么全部失败不会出现部分成功、部分失败的情况。它是一个不可分割的工作单元。典型场景银行转账从账户A扣除100元向账户B增加100元这两个操作必须作为一个整体来执行。如果只执行了第一步而第二步失败数据库就会处于不一致状态。事务保证要么两步都完成要么都不发生。2. ACID 属性事务的四大特性通常用 ACID 来概括A原子性Atomicity事务中的所有操作被视为一个原子单元不可分割。如果事务执行过程中发生错误已经执行的操作会回滚Rollback使数据库回到事务开始前的状态。实现机制回滚日志Undo Log记录操作前的旧值以便在回滚时恢复。C一致性Consistency事务必须使数据库从一个一致性状态转换到另一个一致性状态。一致性由应用层定义例如转账前后账户总金额不变账户余额不能为负等。数据库通过约束主键、外键、唯一性、检查约束以及原子性、隔离性来帮助保证一致性。I隔离性Isolation多个事务并发执行时一个事务的执行不应被其他事务干扰。隔离性通过锁机制和多版本并发控制MVCC来实现。SQL 标准定义了四种隔离级别级别越高隔离性越强但并发性能越低。D持久性Durability一旦事务提交其对数据库的修改就是永久性的即使系统发生故障如断电、崩溃数据也不会丢失。实现机制重做日志Redo Log在事务提交前将修改写入磁盘保证崩溃后可以恢复。3. 事务控制语句在 SQL 中事务通常通过以下语句控制BEGIN或START TRANSACTION显式开始一个事务。COMMIT提交事务使所有修改永久生效。ROLLBACK回滚事务撤销当前事务中已执行的操作。SAVEPOINT设置保存点允许部分回滚。RELEASE SAVEPOINT删除保存点。ROLLBACK TO SAVEPOINT回滚到指定保存点。示例MySQLSTARTTRANSACTION;UPDATEaccountsSETbalancebalance-100WHEREid1;UPDATEaccountsSETbalancebalance100WHEREid2;-- 检查无误后提交COMMIT;-- 如果出错则执行 ROLLBACK;4. 并发问题与隔离级别前面文章已经介绍了三种常见的并发问题问题描述脏读读到其他事务未提交的数据不可重复读同一事务内两次读取同一行数据结果不同幻读同一事务内两次范围查询结果集行数不同SQL 标准定义了四种隔离级别每种级别能避免的问题如下隔离级别脏读不可重复读幻读读未提交可能可能可能读已提交不可能可能可能可重复读不可能不可能可能理论上串行化不可能不可能不可能读未提交性能最高但几乎没有隔离性。读已提交大多数数据库如 Oracle、SQL Server的默认级别避免脏读。可重复读MySQL InnoDB 的默认级别通过 MVCC 间隙锁基本解决了幻读。串行化最高隔离级别所有事务串行执行性能最低。5. 事务的实现机制数据库如何实现 ACID主要依赖以下技术5.1 日志LoggingUndo Log记录事务修改前的数据用于回滚。Redo Log记录事务修改后的数据用于故障恢复。BinlogMySQL用于主从复制和基于时间点的恢复。5.2 锁机制Locking数据库使用锁来控制并发访问共享锁S锁允许事务读取数据其他事务只能加共享锁不能加排他锁。排他锁X锁允许事务修改数据阻止其他事务加任何锁。意向锁用于层次锁表级、行级的协调。间隙锁Gap Lock锁定索引记录之间的间隙防止幻读MySQL InnoDB。5.3 多版本并发控制MVCCMVCC 是“可重复读”和“读已提交”级别常用的并发控制技术。每行数据保存多个版本通过创建版本号和删除版本号或事务ID来管理可见性。读操作通常读取“快照”不加锁快照读写操作加锁当前读。这样读写不互斥极大提高了并发性能。6. 事务在实践中的注意事项6.1 事务的粒度与时长事务应尽可能短小避免长时间占用资源。不要在事务中执行耗时的非数据库操作如网络调用、复杂计算。长事务可能导致锁等待、死锁、Undo 膨胀等问题。6.2 死锁处理多个事务互相等待对方释放锁时就会发生死锁。数据库通常能自动检测死锁并回滚其中一个事务。开发时可以通过约定加锁顺序、使用较低隔离级别、快速提交等方式减少死锁。6.3 隔离级别的选择对一致性要求不高、追求高并发时可用“读已提交”。需要防止不可重复读和幻读时选择“可重复读”或“串行化”。注意不同数据库的默认级别和实现差异如 MySQL 可重复读与 Oracle 可重复读表现不同。6.4 自动提交模式很多数据库客户端默认开启自动提交每个 SQL 语句就是一个独立的事务。在需要多个语句组成一个事务时务必显式开启事务START TRANSACTION并关闭自动提交。7. 总结数据库事务是保证数据一致性和可靠性的核心机制。ACID定义了事务必须具备的特性。隔离级别在一致性与并发性能之间提供权衡。日志、锁、MVCC是数据库实现事务的三大支柱。在实际开发中合理设计事务边界、选择合适的隔离级别、监控死锁和长事务是写出健壮应用的关键。如果你对某个具体方面比如 MVCC 的详细原理、死锁排查方法、特定数据库的实现差异感兴趣我可以继续深入讲解。

更多文章