银鞍照白马,飒沓如流星。
十步杀一人,千里不留行。
1. 事务概念
把需要保证 原子性 、 隔离性 、 一致性 和 持久性 的一个或多个数据库操作称之为一个 事务(transaction )。
2. 事务特性(ACID)
原子性(Atomicity)
一个事务中的所有操作,要么全做,要么全不做,不会结束在中间某个环节;而且事务在执行过程中发生错误时,会被回滚到事务开始前的状态。
隔离性(Isolation)
数据库支持多个并发事务同时对其数据进行读写和修改。多个事务同时使用相同的数据时,每个事务都有一个完整的数据空间,对其他并发事务隔离,互不干扰。隔离性可防止多个事务并发执行时由于交叉执行而导致的数据不一致。
一致性(Consistency)
事务操作前和操作后系统从一个正确的状态,迁移到另一个正确的状态,数据满足完整性约束,数据库保持一致性的状态。
持久性(Durability)
事务执行结束后,对数据的修改是永久的,即使系统故障也不会丢失。
数据库某些操作的原子性和隔离性都是保证一致性的一种手段,在操作执行完成后保证符合所有既定的约束则是一种结果。
- 持久性通过redo log(重做日志)来保证;
- 原子性通过undo log(回滚日志)来保证;
- 隔离性通过MVCC(多版本并发控制)或锁机制来保证;
- 一致性则是通过原子性+隔离性+持久化来保证;
- 事务能够通过AID保证C的过程:C是目的,AID是手段。
3. 事务状态
活动的(active)
事务对应的数据库操作正在执行过程中。
部分提交的(partially committed)
活动的事务最后一个操作执行完成(操作都在内存中执行),但还未刷新到磁盘。
失败的(failed)
活动的或者部分提交的事务,因某些错误(数据库自身的错误、操作系统错误或者直接断电等)而无法继续执行或者人为手动停止。
中止的(aborted)
失败的事务回滚操作执行完成。
提交的(committed)
部分提交的事务修改过的数据已刷新到磁盘。
只有当事务处于提交的或者中止的状态时,一个事务的生命周期才算是结束。

4. 事务语法
4.1 开启事务
语法1. BEGIN [WORK];
BEGIN 语句代表开启一个事务,后边的单词 WORK 可有可无。
语法2. START TRANSACTION [修饰符];
修饰符:
- READ ONLY :标识当前事务是一个只读事务,属于该事务的数据库操作只能读取数据,而不能修改数据。
- READ WRITE :标识当前事务是一个读写事务,属于该事务的数据库操作既可以读取数据,也可以修改数据。
- WITH CONSISTENT SNAPSHOT :启动一致性读。
约束:
- START TRANSACTION后边可以指定修饰符,多个修饰符用逗号隔开;
- READ ONLY 和 READ WRITE 是用来设置事务访问模式的,这两修饰符不能同时设置;事务默认访问模式是读写模式。
- 只读事务中不可以对普通的表(其他事务也能访问到的表)进行增、删、改操作,但可以对临时表做增、删、改操作。
4.2 提交事务
支持三种提交事务的方法:显示提交、自动提交、隐式提交。
显示提交
COMMIT [WORK];
COMMIT 语句就代表提交一个事务,后边的 WORK 可有可无。
自动提交
MySQL 中有一个系统变量 autocommit,其默认值为 ON。默认情况下,如果我们不显式的使用 START TRANSACTION 或者 BEGIN 语句开启一个事务,那么每一条语句都算是一个独立的事务,这种特性称之为事务的自动提交。
关闭自动提交功能的两种方法:
- 显式的的使用 START TRANSACTION 或者 BEGIN 语句开启一个事务。
本次事务提交或者回滚前将会暂时关闭掉自动提交的功能。 - 系统变量 autocommit 的值设置为 OFF。
写入的多条语句将属于同一个事务,直到显式的写出 COMMIT 语句来把这个事务提交掉,或者显式的写出 ROLLBACK 语句来把这个事务回滚掉。
隐式提交
会导致事务隐式提交的语句包括:
-
定义或修改数据库对象的数据定义语言(Data definition language,缩写为: DDL )
使用DDL(CREATE、ALTER、DROP等)语句去修改数据库对象(数据库、表、视图、存储过程等)时,会隐式的提交前边语句所属于的事务 -
隐式使用或修改 mysql 数据库中的表
使用ALTER USER、 CREATE USER、 DROP USER、 GRANT、 RENAME USER、 REVOKE、 SET PASSWORD等语句时也会隐式的提交前边语句所属于的事务。 -
事务控制或关于锁定的语句
当一个事务还没提交或者回滚时就又使用START TRANSACTION或者BEGIN语句开启另一个事务时,会隐式的提交上一个事务。
当前的autocommit系统变量的值为OFF,手动调为ON时,也会隐式的提交前边语句所属的事务。
—使用 LOCK TABLES、 UNLOCK TABLES 等关于锁定的语句也会隐式的提交前边语句所属的事务。 -
加载数据的语句
使用 LOAD DATA 语句来批量往数据库中导入数据时,也会隐式的提交前边语句所属的事务。 -
关于 MySQL 复制的一些语句
使用 START SLAVE、 STOP SLAVE、 RESET SLAVE、 CHANGE MASTER TO 等语句时也会隐式的提交前边语句所属的事务。 -
其它的一些语句
使用ANALYZE TABLE、 CACHE INDEX、 CHECK TABLE、 FLUSH、 LOAD INDEX INTO CACHE、 OPTIMIZETABLE、 REPAIR TABLE、 RESET 等语句也会隐式的提交前边语句所属的事务。
4.3 手动中止事务
ROLLBACK [WORK];
ROLLBACK 语句就代表中止并回滚一个事务,后边的 WORK 可有可无。
4.4 支持事务的存储引擎
MySQL 中并不是所有存储引擎都支持事务的功能,目前只有 InnoDB 和 NDB 存储引擎支持,如果某个事务中包含了修改使用不支持事务的存储引擎的表,那么对该使用不支持事务的存储引擎的表所做的修改将无法进行回滚。
4.5 保存点
在事务对应的数据库语句中打几个点,我们在调用 ROLLBACK 语句时可以指定回滚到哪个点,而不是回到最初的原点。
- 定义保存点:
SAVEPOINT 保存点名称;
- 回滚到某个保存点:
ROLLBACK [WORK] TO [SAVEPOINT] 保存点名称;
WORK 和 SAVEPOINT 是可有可无。ROLLBACK 语句后边不跟随保存点名称的话,会直接回滚到事务执行之前的状态。
- 删除某个保存点:
RELEASE SAVEPOINT 保存点名称;

阅读推荐《MySQL是怎样运行的:从根儿上理解MySQL》、《高性能MySQL》、《MySQL45讲》




