18.2 事务的概念
- 原子性(Atomic) undo log
- 一致性(Consistency) 持久性 + 隔离性 + 原子性
- 隔离性(Isolation) MVCC 或锁
- 持久性(Durability) redo log
事务是一个抽象的概念,其实对应着一个或多个数据库操作。事务大致分为以下几个状态:
- 活动的:事务对应的数据库操作正在执行过程中;
- 部分提交的:当事务中的最后一个操作执行完成,但由于操作都在内存中执行,所造成的影响没有刷新到磁盘时,就是部分提交状态;
- 失败的:事务处于活动状态或部分提交状态,遭遇某些错误而无法执行;
- 中止的:事务执行半截而变为失败状态,就需要撤销失败事务对当前数据库造成的影响:回滚。回滚操作执行完毕后,数据库恢复到了执行事务之前的状态,此时该事务处于中止状态;
- 提交的:当一个处于部分提交状态的事务将修改过的数据都刷新到磁盘中后,就是提交状态。
只有当事务处于提交和终止状态时,生命周期才算结束。
18.3 MySQL 中事务的用法
开启事务
BEGIN [WORK];
START TRANSACTION;
上述两个语句都可以开启一个事务。但是 START TRANSACTION;
后面可以跟随几个修饰符:
READ ONLY
标识当前事务是只读事务,即属于该事务的数据库操作只能读取数据,不能修改数据;READ WRITE
标识当前事务是一个读写事务。WITEH CONSISTENT SNAPSHOT
启动一致性读。
多个修饰符可以用逗号分隔开。
提交事务
开启事务后就可以继续编写需要放到该事务中的语句。当最后一条语句写完后,可以提交该事务:
COMMIT [WORK];
手动中止事务
如果发现某条语句写错了,可以将数据库恢复到事务执行之前的样子:
ROLLBACK [WORK];
支持事务的存储引擎
只有 InnoDB 和 NDB 存储引擎支持。
自动提交
有一个系统变量autocommit
,用来自动提交事务,其默认值为 ON,如果不显式使用**BEGIN**
或者**START TRANSACTION**
开启一个事务,那么每一条语句都算是一个独立的事务,这种特性为事务的自动提交。
如果向关闭自动提交,可以使用如下方法:
显式使用
**BEGIN**
或者**START TRANSACTION**
开启一个事务,这样在本次事务提交或回滚前都会暂时关闭自动提交功能。把系统变量的值
autocommit
设为 OFF:
SET autocommit = OFF
这样写入的多条语句就算属于同一个事务了,直到显式写出COMMIT
把这个事务提交掉,或者显式写出ROLLBACK
把该事务回滚掉。
隐式提交
如果我们输入某些语句,且这些语句会导致之前的事务悄悄提交掉(就像输入了 COMMIT 语句一样),那么这种情况为隐式提交。
- 定义或修改数据库对象的数据定义语言
当使用 CREATE、ALTER、DROP 等语句修改数据库对象时,就会隐式提交前面语句所属的事务:
- 隐式使用或修改“mysql”数据库中的表
使用 ALTER USER、 CREATE USER、DROP USER、GRANT、RENAME USER、REVOKE、SET PASSWORD 等语句时,也会隐式提交前面语句所属的事务。
- 事务控制或关于锁定的语句
当在一个事务还没提交或者还没回滚时就又开启另一个事务,此时就会隐式提交上一个事务。
在当前的autocommit
系统变量值为 OFF 时,而手动调为 ON 时,也会隐式提交。
使用 LOCK TABLES、UNLOCK TABLES 等关于锁定的语句时,也会隐式提交前面语句所属的事务。
- 加载数据的语句
比如使用 LOAD DATA 语句向数据库中批量导入数据时,也会隐式提交。
- 关于MySQL复制的一些语句
…
保存点
在事务对应的语句中打几个点,这样在调用ROLLBACK
语句时,就可以指定回滚到哪个点,而不是会导事务前。
定义保存点: SAVEPOINT 保存点名称;
当回滚到保存点时,使用: ROLLBACK [WORK] TO [SAVEPOINT] 保存点名称;
删除保存点,使用: RELEASE SAVEPOINT 保存点名称;