MySQL 默认的两种事务型存储引擎:InnoDB
和 NDB Cluster
。另外第三方支持事务的存储引擎,如:XtraDB
和 PBXT
。
自动提交(AUTOCOMMIT)
MySQL 默认的提交方式。即:若不是一个显式的开始一个事务,均当每个查询当做一个事务执行提交操作。
可在当前连接中,设置 AUTOCOMMIT
变量来启用或禁用自动提交模式。
- 1 或 ON 表示启用;0 或 OFF 表示禁用。
- 当为 0 时,所有查询都是在一个事务中直至
COMMIT
(提交) 或ROLLBACK
(回滚)才结束,并开启另一个新的事物。
- 当为 0 时,所有查询都是在一个事务中直至
- 对于非事务型的表,如 MyISAM 或内存表,修改
AUTOCOMMIT
不会有任何影响。- 但那个人对于这类表也没有
COMMIT
、ROLLBACK
的概念;相当于一直启用了AUTOCOMMIT
。
- 但那个人对于这类表也没有
- 其他一些命令,会在执行前强制执行
COMMIT
提交当前事务。如数据定义语言 DDL。比如:ALTER TABLE
、LOCK TABLES
等- 可通过检查对应版本的官方文档确认可能导致自动提交的语句列表。
- MySQL 可通过执行
SET TRANSACTION ISOLATION LEVEL
命令来设置隔离级别,并在下一次事务开始时生效。- 也可在配置文件中设置隔离级别,以改变整个数据库的隔离级别。
在事务中混合使用存储引擎
- MySQL 服务器层不管理事务,事务由下层的存储引擎实现;所以,同事务使用多个存储引擎是不可靠的。
- 若事务混合事务型和非事务型(如:InnoDB 和 MyISAM),正常提交下无问题;但异常情况,则无法进行事务性的回滚。
- 大多数的非事务型表下,回滚不会有提醒
隐式和显式锁定
InnoDB 采用两阶段锁定协议(two-phase locking protocol)。
- 隐式锁定:事务过程,随时可执行锁定,锁只有在 COMMIT 或 ROLLBACK 时才会释放,并且同时刻释放。
- InnoDB 会根据隔离级别,在需要时自动加锁。
- 显式锁定:如下不属于 SQL 规范
SELECT ... LOCK IN SHARE MODE
SELECT ... FOR UPDATE
- MySQL 支持的
LOCK TABLES
和UNLOCK TABLES
语句是服务器层实现,与存储引擎无关。
建议:事务中禁用 **AUTOCOMMIT
,可以使用 LOCK TABLES
之外,其他任何时候不要显式执行 LOCK TABLES
**。