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