MySQL 中的事務(wù)控制機制
事務(wù)控制是 MySQL 的重要特性之一。在 MySQL 中,InnoDB 和 NDB Cluster 是常見的事務(wù)型存儲引擎。
1. 自動提交
默認情況下,MySQL 是自動提交(autocommit)的。也就意味著:如果不是顯式地開始一個事務(wù),每個查詢都會被當做一個事務(wù)執(zhí)行 commit。這是和 Oracle 的事務(wù)管理明顯不同的地方,如果應(yīng)用是從Oracle 數(shù)據(jù)庫遷移至 MySQL 數(shù)據(jù)庫,則需要確保應(yīng)用中是否對事務(wù)進行了明確的管理。
在當前連接中,可以通過設(shè)置 autocommit 來修改自動提交模式:
mysql> show variables like 'autocommit';
+---------------+-------+
| Variable_name | Value |
+---------------+-------+
| autocommit | ON |
+---------------+-------+
1 row in set (0.00 sec)
mysql> set autocommit = 1;
Query OK, 0 rows affected (0.00 sec)
-- 1或ON表示啟用自動提交模式,0或OFF表示禁用自動提交模式
如果設(shè)置了autocommit=0,當前連接所有事務(wù)都需要通過明確的命令來提交或回滾。
對于 MyISAM 這種非事務(wù)型的表,修改 autocommit 不會有任何影響,因為非事務(wù)型的表,沒有 commit或 rollback 的概念,它會一直處于 autocommit 啟用的狀態(tài)。
有些命令,在執(zhí)行之前會強制執(zhí)行 commit 提交當前連接的事務(wù)。比如 DDL 中的 alter table,以及l(fā)ock tables 等語句。
2. 隔離級別調(diào)整
默認情況下,MySQL 的隔離級別是可重復讀(repeatable read)。MySQL 可以通過 set transaction_isolation 命令來調(diào)整隔離級別,新的隔離級別會在下一個事務(wù)開始時生效。
調(diào)整隔離級別的方法有兩種:
-
臨時:在 MySQL 中直接用命令行執(zhí)行:
mysql> show variables like 'transaction_isolation'; +-----------------------+-----------------+ | Variable_name | Value | +-----------------------+-----------------+ | transaction_isolation | REPEATABLE-READ | +-----------------------+-----------------+ 1 row in set (0.00 sec) mysql> SET transaction_isolation = 'REPEATABLE-READ'; Query OK, 0 rows affected (0.00 sec)
-
永久:將以下兩個參數(shù)添加至配置文件 my.cnf,并重啟 MySQL:
transaction_isolation = 'REPEATABLE-READ'
3. 事務(wù)中使用不同的存儲引擎
MySQL 的服務(wù)層并不負責事務(wù)的處理,事務(wù)都是由存儲引擎層實現(xiàn)。
在同一事務(wù)中,使用多種存儲引擎是不可靠的,尤其在事務(wù)中混合使用了事務(wù)型和非事務(wù)型的表。如同一事務(wù)中,使用了 InnoDB 和 MyISAM 表:
- 如果事務(wù)正常提交,不會有什么問題;
- 如果事務(wù)遇到異常需要回滾,非事務(wù)型的表就無法撤銷表更,這就會直接導致數(shù)據(jù)處于不一致的狀態(tài)。
4. 小結(jié)
本小節(jié)主要介紹了 MySQL 中事務(wù)控制的一些特點,如何調(diào)整自動提交(autocommit)、如何調(diào)整隔離級別調(diào)整、以及講解了在事務(wù)中使用混合存儲引擎的缺點。