18.2 事务的概念

  • 原子性(Atomic) undo log
  • 一致性(Consistency) 持久性 + 隔离性 + 原子性
  • 隔离性(Isolation) MVCC 或锁
  • 持久性(Durability) redo log

事务是一个抽象的概念,其实对应着一个或多个数据库操作。事务大致分为以下几个状态

  • 活动的:事务对应的数据库操作正在执行过程中;
  • 部分提交的:当事务中的最后一个操作执行完成,但由于操作都在内存中执行,所造成的影响没有刷新到磁盘时,就是部分提交状态;
  • 失败的:事务处于活动状态或部分提交状态,遭遇某些错误而无法执行;
  • 中止的:事务执行半截而变为失败状态,就需要撤销失败事务对当前数据库造成的影响:回滚。回滚操作执行完毕后,数据库恢复到了执行事务之前的状态,此时该事务处于中止状态;
  • 提交的:当一个处于部分提交状态的事务将修改过的数据都刷新到磁盘中后,就是提交状态。

image.png
只有当事务处于提交终止状态时,生命周期才算结束。

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**开启一个事务,那么每一条语句都算是一个独立的事务,这种特性为事务的自动提交。

如果向关闭自动提交,可以使用如下方法:

  1. 显式使用**BEGIN**或者**START TRANSACTION**开启一个事务,这样在本次事务提交或回滚前都会暂时关闭自动提交功能。

  2. 把系统变量的值autocommit设为 OFF:

SET autocommit = OFF
这样写入的多条语句就算属于同一个事务了,直到显式写出COMMIT把这个事务提交掉,或者显式写出ROLLBACK把该事务回滚掉。

隐式提交

如果我们输入某些语句,且这些语句会导致之前的事务悄悄提交掉(就像输入了 COMMIT 语句一样),那么这种情况为隐式提交

  • 定义或修改数据库对象的数据定义语言

当使用 CREATE、ALTER、DROP 等语句修改数据库对象时,就会隐式提交前面语句所属的事务:image.png

  • 隐式使用或修改“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 保存点名称;