事务的核心概念
事务是由一组 DML 语句组成的逻辑单元,这些语句在逻辑上存在强相关性。这一组 SQL 要么全部成功,要么全部失败,是一个不可分割的整体。
在实际业务中,比如银行转账,扣款和入账必须同时完成。如果只扣了钱没入账,或者反之,数据就会出错。MySQL 提供机制来保证这种效果。一个完整的事务,绝对不是简单的 SQL 集合,它需要满足四个属性,也就是常说的 ACID:
- 原子性 (Atomicity):事务中的所有操作,要么全部完成,要么全部不完成。执行过程中发生错误,会被回滚到事务开始前的状态,就像这个事务从来没有执行过一样。
- 一致性 (Consistency):在事务开始之前和结束以后,数据库的完整性没有被破坏。写入的数据必须符合所有预设规则,包括精确度、关联性以及后续数据库可以自发地完成预定的工作。
- 隔离性 (Isolation):数据库允许多个并发事务同时读写修改数据。隔离性防止多个事务交叉执行导致数据不一致。事务隔离分为不同级别,包括读未提交、读提交、可重复读和串行化。
- 持久性 (Durability):事务处理结束后,对数据的修改就是永久的,即便系统故障也不会丢失。
只要做到了原子性、隔离性和持久性,技术上就能保证数据的一致性。
为什么需要事务
事务被设计出来,本质是为了简化应用层的编程模型。当应用程序访问数据库时,我们不需要去考虑各种潜在的错误和并发问题。有了事务,要么提交,要么回滚,不用操心网络异常、服务器宕机或者同时更改同一个数据的情况。
因此,事务本质上是为应用层服务的,而不是伴随着数据库系统天生就有的。
引擎支持
在 MySQL 中,只有使用了 InnoDB 存储引擎的数据库或表才支持事务,MyISAM 不支持。
可以通过以下命令查看当前支持的引擎:
mysql> show engines;
输出结果中可以看到 InnoDB 的 Transactions 字段为 YES,而 MyISAM 则为 NO。这意味着如果你开启了事务功能但用的是 MyISAM 表,事务特性是无效的。
事务提交方式
事务的提交方式常见的有两种:自动提交和手动提交。
默认情况下,MySQL 是开启自动提交的。我们可以通过变量查看和修改:
-- 查看自动提交状态
show variables like 'autocommit';
-- 关闭自动提交(进入手动模式)
set autocommit=0;
-- 开启自动提交
set autocommit=1;
注意,一旦输入 begin 或者 start transaction,事务便必须要通过 commit 提交才会持久化,这与是否设置 autocommit 无关。开启事务后,当前的会话会自动切换到非自动提交模式。
实操演示
为了便于演示,我们先准备一张测试表。这里修正了一个拼写错误,将 blance 改为标准的 balance。
create table if account(
id ,
name () ,
balance (,)
) ENGINEInnoDB CHARSETUTF8;


