一、什么是数据库事务
数据库事务是数据库管理系统中的一个核心概念,用于确保一组操作要么全部成功执行,要么全部不执行,从而维护数据的完整性和一致性。
二、ACID特性详解
1、原子性(Atomicity)
事务中的所有操作要么全部成功提交,要么全部失败回滚。例如转账操作包含扣款和入账两个步骤,若中途失败,系统会自动回滚所有操作。
2、一致性(Consistency)
事务执行前后数据库必须满足预定义的一致性约束(如唯一性、外键约束)。例如账户总金额在转账前后保持不变。
3、隔离性(Isolation)
多个并发事务的执行互不干扰。例如事务A未提交时,事务B无法读到其未提交的修改。
4、持久性(Durability)
事务提交后,修改永久生效,即使系统故障也不丢失。例如转账成功后数据立即写入持久化存储。
三、ACID特性的实现原理
1、原子性(Atomicity)的实现
原子性通过Undo Log(回滚日志)实现:
- 事务执行前,系统会记录数据修改前的状态到Undo Log。
- 如果事务需要回滚,系统会根据Undo Log执行逆向操作恢复数据。
- 例如转账事务失败时,系统会利用Undo Log将账户余额恢复原状。
2、一致性(Consistency)的实现
一致性通过多种机制共同保障 :
- 数据库约束:主键、外键、唯一约束等。
- 业务规则校验:如转账前后总金额不变的校验。
- 原子性、隔离性和持久性的协同作用。
- 触发器、存储过程等辅助机制。
3、隔离性(Isolation)的实现
隔离性主要通过以下技术实现:
(1)锁机制
- 共享锁(S锁):读锁,允许多事务并发读。
- 排他锁(X锁):写锁,独占数据访问权。
- 意向锁:提高锁检测效率。
- 间隙锁(Gap Lock):防止幻读。
-
(2)MVCC(多版本并发控制)
- 每个事务看到的是数据在特定时间点的快照。
- 通过版本链实现读不阻塞写、写不阻塞读。
- InnoDB通过隐藏的DB_TRX_ID、DB_ROLL_PTR等字段实现。
4、持久性(Durability)的实现
持久性通过Redo Log(重做日志)保障:
(1)事务提交时,修改先写入Redo Log Buffer
(2)根据innodb_flush_log_at_trx_commit
参数决定刷盘策略
- 1(默认):事务提交时立即刷盘
- 0:每秒刷盘一次
- 2:写入OS缓存后由系统决定刷盘时机
(3)系统崩溃恢复时,通过Redo Log重放已提交事务
5、技术实现示例(MySQL InnoDB)
-- 查看当前事务隔离级别
SELECT @@transaction_isolation;
-- 设置隔离级别为可重复读
SET GLOBAL TRANSACTION ISOLATION LEVEL REPEATABLE READ;
-- 查看InnoDB日志相关参数
SHOW VARIABLES LIKE 'innodb_log%';
6、ACID实现的协同关系
四大特性相互关联:
- 原子性是基础,确保事务的"全或无"
- 隔离性控制并发,避免事务间干扰
- 持久性保证结果永久存储
- 三者共同保障数据库状态的一致性
通过上述机制的组合,数据库系统能够在保证数据可靠性的同时,提供合理的并发性能。
四、大白话理解事务
用大白话来说,数据库事务(Transaction)就像你给数据库下的一个「打包任务」——要么所有操作全部成功,数据库进入新状态;要么全部失败,数据保持原样,仿佛什么都没发生过。
1、举个栗子:网购付款
- 你付款 → 账户扣钱
- 商家收款 → 账户加钱
- 库存减少 → 商品库存-1
如果这三步全部完成,才算交易成功;如果中途任何一步失败(比如扣钱后库存不足),数据库会自动回滚(撤销之前的操作),就像什么都没发生。
2、事务的核心特征
- 原子性:打包操作,要么全做,要么全不做。
- 一致性:操作后数据必须符合规则(比如余额不能为负数)。
- 隔离性:多人同时操作时互不干扰(比如你和朋友同时抢票不会重复卖同一张)。
- 持久性:一旦成功,结果永久保存(断电也不丢数据)。
3、什么时候用事务
只要一组操作必须整体成功的场景都用它!比如:
- 银行转账(必须同时扣钱和加钱)
- 订单支付(扣款、减库存、生成订单必须联动)
- 批量数据处理(比如导入100条数据,中间出错就全放弃)
4、操作示例
BEGIN TRANSACTION; -- 开始!
UPDATE 账户 SET 余额=余额-100 WHERE 用户=你;
UPDATE 账户 SET 余额=余额+100 WHERE 用户=商家;
COMMIT; -- 成功了,永久保存!
-- 如果中途出错:
ROLLBACK; -- 失败了,全部撤回!
5、总结
数据库事务就是让数据库操作要么彻底成功,要么彻底失败的机制,是保证数据安全的保险丝,比如你永远不用担心“钱扣了但商品没到账”这种离谱bug!