MySQL 事务自动提交机制总结
事务的自动提交机制
在 InnoDB
,所有用户活动都发生在事务中。
InnoDB
默认采用事务自动提交(autocommit
)机制。也就是说,如果不是显式开启一个事务,则每条 SQL 语句都形成独立事务。如果该语句执行后没有返回错误,MySQL 会自动执行 COMMIT
。但如果该语句返回错误,则根据错误情况执行 COMMIT
或 ROLLBACK
。
如何修改当前会话的提交模式?
1 | SHOW VARIABLES LIKE 'AUTOCOMMIT'; |
注意:
- 关闭后,会话将始终开启一个事务。直到你显式提交或回滚该事务后,一个新事务又被开启。
- 如果一个关闭了
autocommit
的会话没有显式提交事务,然后会话被关闭,MySQL 将回滚该事务。 - 有一些命令,在执行之后会强制执行
COMMIT
提交当前的活动事务。例如:ALTER TABLE
LOCK TABLES
提交多语句事务
如何在一个事务中组合多条 SQL 语句(multiple-statement transaction)?有两种方式:
方式一:显式关闭当前会话的
autocommit
,然后提交或回滚事务。1
2
3SET autocommit=0;
INSERT INTO parent VALUES (10, 'Heikki');
COMMIT;方式二:如果不想关闭
autocommit
,可以通过START TRANSACTION
或BEGIN
语句显式开启事务,然后通过COMMIT
或ROLLBACK
语句显式结束事务。1
2
3
4
5START TRANSACTION;
INSERT INTO parent VALUES (15, 'John');
INSERT INTO parent VALUES (20, 'Paul');
DELETE FROM parent WHERE b = 'Heikki';
ROLLBACK;
最终结果:
1 | SELECT * FROM parent; |
在事务中混合使用存储引擎问题
MySQL 服务器层不管理事务,事务是由下层的存储引擎实现的。所以在同一个事务中,使用多种存储引擎是不可靠的。
如果在事务中混合使用了事务型和非事务型的表(例如 InnoDB
和 MyISAM
表),可能会有意想不到的情况发生。请看下例:
1 | --引入一张 MyISAM 表 |
示例一,在事务中混合使用存储引擎,出现报错:
1 | START TRANSACTION; |
示例二,当事务回滚,非事务型的表上的变更无法撤销,这会导致数据库处于不一致的状态,这种情况很难修复,事务的最终结果将无法确定。
1 | START TRANSACTION; |
所以,为每张表选择合适的存储引擎非常重要。
参考
《高性能 MySQL》
https://dev.mysql.com/doc/refman/5.7/en/innodb-consistent-read.html
https://dev.mysql.com/doc/refman/5.7/en/sql-syntax-transactions.html