mysql菜鸟教程

专栏导航

15.1 什么是事务?ACID原则

在日常生活中,有许多操作是不可分割的。比如,你用银行卡给朋友转账 1000 元,这个过程实际上包含两个步骤:从你的账户扣除 1000 元,向朋友的账户增加 1000 元。这两个步骤必须要么都成功,要么都不成功,否则就会出现你的钱扣了但朋友没收到,或者钱没扣却给朋友加了钱的情况。在数据库中,这种“要么全做,要么全不做”的操作单元就是事务

一、什么是事务?

事务 是数据库管理系统执行过程中的一个逻辑单元,它由一组 SQL 语句组成,这些语句作为一个整体一起提交或一起撤销。事务是数据库并发控制故障恢复的基本单位。

事务的典型例子:银行转账

-- 假设有两个账户:A 和 B
-- 从 A 转 100 元到 B

START TRANSACTION;                  -- 开始事务
UPDATE accounts SET balance = balance - 100 WHERE account_id = 'A';
UPDATE accounts SET balance = balance + 100 WHERE account_id = 'B';
COMMIT;                              -- 提交事务

如果在执行完第一个 UPDATE 后系统崩溃,第二个 UPDATE 还没来得及执行,数据库通过事务机制会在系统恢复后自动回滚第一个操作,确保两个账户余额总和不变。

二、事务的 ACID 原则

为了保证事务的正确性和可靠性,数据库事务必须满足四个特性,即 ACID

特性

全称

含义

类比

A

原子性

事务是一个不可分割的整体,要么全部执行,要么全部不执行。

转账扣款和加款必须同时成功或同时失败。

C

一致性

事务执行前后,数据库都必须处于一致性状态(数据满足所有约束规则)。

转账前后,两个账户的总金额不变。

I

隔离性

并发执行的事务之间互不干扰,一个事务的中间状态对其他事务不可见。

同时发生的两笔转账互不影响。

D

持久性

一旦事务提交,它对数据的修改就是永久性的,即使系统崩溃也不会丢失。

转账成功后,即使宕机,钱也不会丢。

下面我们逐一深入解释。

原子性(Atomicity)

原子性要求事务中的所有操作要么全部成功,要么全部失败回滚。如果事务在执行过程中遇到错误,已经执行的操作必须被撤销,就像从未发生过一样。

在 MySQL 中,原子性通过 回滚日志(undo log) 实现。当事务对数据进行修改时,InnoDB 会先生成 undo log 记录修改前的状态,如果事务需要回滚,就根据 undo log 恢复数据。

一致性(Consistency)

一致性是指事务必须使数据库从一个一致性状态转变到另一个一致性状态。这里的“一致性”是指数据满足所有的约束规则,比如主键唯一、外键正确、检查约束等。

事务的原子性、隔离性和持久性最终都是为了保证一致性。例如,转账后两个账户的总余额不变,这就是业务上的一致性要求。

隔离性(Isolation)

隔离性保证多个事务并发执行时,一个事务的执行不会被其他事务干扰。数据库系统通过锁机制多版本并发控制(MVCC) 来实现隔离性。

ANSI/ISO SQL 标准定义了四个隔离级别,从低到高依次为:

  • 读未提交:可能读到其他事务未提交的数据(脏读)。

  • 读已提交:只能读到已提交的数据,可避免脏读。

  • 可重复读:同一事务内多次读取同一数据结果一致(MySQL InnoDB 默认级别),可避免脏读和不可重复读。

  • 可串行化:事务串行执行,性能最低,可避免所有并发问题(包括幻读)。

不同的隔离级别可以解决不同的并发一致性问题:

问题

描述

隔离级别要求

脏读

读到另一个事务未提交的数据

至少读已提交

不可重复读

同一事务内两次读取同一数据,结果不同(被其他事务修改并提交)

至少可重复读

幻读

同一事务内两次查询(范围查询),结果集行数不同(其他事务插入或删除了行)

可串行化

持久性(Durability)

持久性保证一旦事务提交,其对数据的修改就是永久性的,即使随后系统崩溃也不会丢失。MySQL 通过 重做日志(redo log) 实现持久性。在事务提交时,InnoDB 会将修改记录写入 redo log 并落盘,然后才修改数据页。即使数据页还没来得及写回磁盘,系统重启后也能通过 redo log 恢复已提交的事务。

三、MySQL 中的事务使用

在 MySQL 中,只有 InnoDB 存储引擎支持事务。事务的基本操作包括:

START TRANSACTION;  -- 或 BEGIN;  开始事务
-- 执行一系列 SQL 语句
COMMIT;             -- 提交事务,使更改永久生效
ROLLBACK;           -- 回滚事务,撤销所有更改
SAVEPOINT 点名;      -- 设置保存点,可部分回滚
ROLLBACK TO 点名;    -- 回滚到指定保存点

默认情况下,MySQL 是自动提交的,即每条 SQL 语句结束后自动提交。可以通过 SET AUTOCOMMIT = 0; 关闭自动提交,之后需要手动 COMMIT

四、小结

  • 事务 是数据库操作的逻辑单元,确保一组操作要么全部成功,要么全部失败。

  • ACID 是事务必须满足的四个特性:原子性、一致性、隔离性、持久性。

  • 原子性通过 undo log 实现,持久性通过 redo log 实现,隔离性通过锁和 MVCC 实现,一致性是事务的最终目标。

  • MySQL 的 InnoDB 引擎完整支持事务,并提供了丰富的隔离级别供开发者选择。

理解事务是编写可靠数据库应用的基础,下一节我们将学习如何在实际中开始、提交和回滚事务,以及如何处理并发带来的问题。


所有评论

关于我 备案号:蜀ICP备2023042032号-1