MySQL 事務小夥伴們都懂,通過 begin 開啟事務,通過 commit 提交事務或者通過 rollback 回滾事務。
在前面的文章中,鬆哥也和大家聊了一些事物原理以及相關的細節,小夥伴們可以回顧一下:
正常來說,當我們開啟一個事務之後,需要 commit 或者 rollback 來結束一個事務的,但是有時候,一些操作會自動幫我們提交事務,如果大家不瞭解隱式事務的話,那麼在具體使用事務的事務可能就會遭遇一些莫名其妙的問題。
首先一點就是 DDL 操作會隱式提交事務,這個鬆哥在之前的文章中其實有說過,我們再來一起回顧下:
所有的 DDL 語句都會導致事務隱式提交,換句話說,當你在執行 DDL 語句前,事務就已經提交了。這就意味著帶有 DDL 語句的事務將來沒有辦法 rollback。
我舉一個簡單的例子,大家一起來看下:
我們來一起看下我這裡的測試邏輯:
到第六步的時候,我們發現查詢到的資料只剩三條了,說明第五步的回滾並沒有生效。原因就在於執行 alter 之前,事務已經被隱式提交了。
所以小夥伴們在日常開發中,最好不要在事務中混有 DDL 語句,DDL 語句和 DML 語句分開寫。
對於上面的案例,如果大家去掉第四步的 alter,那麼回滾是可以回滾成功的,這個小夥伴們自己來測試,我就不演示了。
當然 DDL 操作可不僅僅是 alter,其他的如 CREATE、DROP 等操作也會導致事務隱式提交,這裡鬆哥就不一一舉例了,小夥伴們可以自行嘗試。
DDL 和 DML 大家應該經常接觸到,但是 DCL 可能有小夥伴不清楚,DCL 其實就是 Data Control Language,中文譯作資料控制語言,我們日常授權或者回收資料庫上的許可權所使用的 GRANT、REVOKE 等,就算是 DCL 操作。
我舉個簡單例子:
可以看到,跟第一小節的測試步驟一樣,只不過第四步換成一個 GRANT 語句,那麼最終的事務回滾也會失效,原因就在於事務已經提交了。
當然,除了 GRANT 和 REVOKE 之外,其他的建立、更新或者刪除使用者的操作也會導致事務隱式提交。主要有:
一個事務還沒提交,結果你又開啟了一個新的事務,那麼此時前一個事務也會隱式提交。看個例子:
這個好理解,不多說。
給表上鎖、解鎖也會導致事務隱式提交。如下:
上鎖的 SQL 如 lock tables table_name read|write
,會導致事務隱式提交,解鎖的 SQL 如 unlock tables
也會導致事務被隱式提交。
除了表鎖,一些全域性鎖如 FTWRL 也會導致事務的隱式提交,如下:
之前鬆哥有教大家如何大家 MySQL 主從:
我們在從機上執行的一些操作如 start slave
、stop slave
、reset slave
以及 change master to
等語句也會隱式提交事務。
其他的一下操作如重新整理許可權(flush privileges)、優化表(optimize table)、修復表(repair table)等操作,也會導致事務的隱式提交。
我在網上看有人說 LOAD DATA 會隱式提交事務,鬆哥親測貌似並不會,如下圖:
LOAD DATA 似乎並沒有導致事務隱式提交,歡迎大家提出不同見解一起探討。
那麼多隱式提交,我怎麼記得住呀?其實不用背,你只要記著事務裡只寫增刪改查(INSERT/DELETE/UPDATE/SELECT),就不會錯啦!