MySQL 默认的两种事务型存储引擎:InnoDBNDB Cluster。另外第三方支持事务的存储引擎,如:XtraDBPBXT

自动提交(AUTOCOMMIT)

MySQL 默认的提交方式。即:若不是一个显式的开始一个事务,均当每个查询当做一个事务执行提交操作。

可在当前连接中,设置 AUTOCOMMIT 变量来启用或禁用自动提交模式。

image.png

  • 1 或 ON 表示启用;0 或 OFF 表示禁用。
    • 当为 0 时,所有查询都是在一个事务中直至 COMMIT(提交) 或 ROLLBACK(回滚)才结束,并开启另一个新的事物。
  • 对于非事务型的表,如 MyISAM 或内存表,修改 AUTOCOMMIT 不会有任何影响。
    • 但那个人对于这类表也没有 COMMITROLLBACK 的概念;相当于一直启用了 AUTOCOMMIT
  • 其他一些命令,会在执行前强制执行 COMMIT 提交当前事务。如数据定义语言 DDL。比如:ALTER TABLELOCK TABLES
    • 可通过检查对应版本的官方文档确认可能导致自动提交的语句列表。
  • MySQL 可通过执行 SET TRANSACTION ISOLATION LEVEL 命令来设置隔离级别,并在下一次事务开始时生效。
    • 也可在配置文件中设置隔离级别,以改变整个数据库的隔离级别。
    • image.png

在事务中混合使用存储引擎

  • MySQL 服务器层不管理事务,事务由下层的存储引擎实现;所以,同事务使用多个存储引擎是不可靠的。
    • 若事务混合事务型和非事务型(如:InnoDB 和 MyISAM),正常提交下无问题;但异常情况,则无法进行事务性的回滚。
  • 大多数的非事务型表下,回滚不会有提醒

隐式和显式锁定

InnoDB 采用两阶段锁定协议(two-phase locking protocol)。

  • 隐式锁定:事务过程,随时可执行锁定,锁只有在 COMMIT 或 ROLLBACK 时才会释放,并且同时刻释放。
    • InnoDB 会根据隔离级别,在需要时自动加锁。
  • 显式锁定:如下不属于 SQL 规范
    • SELECT ... LOCK IN SHARE MODE
    • SELECT ... FOR UPDATE
    • MySQL 支持的 LOCK TABLESUNLOCK TABLES 语句是服务器层实现,与存储引擎无关。

建议:事务中禁用 **AUTOCOMMIT,可以使用 LOCK TABLES 之外,其他任何时候不要显式执行 LOCK TABLES**。