愛伊米

咦,為什麼我的事務回滾不了

MySQL 事務小夥伴們都懂,透過 begin 開啟事務,透過 commit 提交事務或者透過 rollback 回滾事務。

在前面的文章中,松哥也和大家聊了一些事物原理以及相關的細節,小夥伴們可以回顧一下:

MVCC 水略深,但是弄懂了真的好爽!一致性檢視是啥時候建立的?四個案例看懂 MySQL 事務隔離級別

正常來說,當我們開啟一個事務之後,需要 commit 或者 rollback 來結束一個事務的,但是有時候,一些操作會自動幫我們提交事務,如果大家不瞭解隱式事務的話,那麼在具體使用事務的事務可能就會遭遇一些莫名其妙的問題。

1。 DDL 操作

首先一點就是 DDL 操作會隱式提交事務,這個松哥在之前的文章中其實有說過,我們再來一起回顧下:

所有的 DDL 語句都會導致事務隱式提交,換句話說,當你在執行 DDL 語句前,事務就已經提交了。這就意味著帶有 DDL 語句的事務將來沒有辦法 rollback。

我舉一個簡單的例子,大家一起來看下:

咦,為什麼我的事務回滾不了

我們來一起看下我這裡的測試邏輯:

首先查詢總記錄數有四條。開啟一個事務。執行一條刪除語句。alter 表,新增一個欄位。回滾。再次查詢資料。

到第六步的時候,我們發現查詢到的資料只剩三條了,說明第五步的回滾並沒有生效。原因就在於執行 alter 之前,事務已經被隱式提交了。

所以小夥伴們在日常開發中,最好不要在事務中混有 DDL 語句,DDL 語句和 DML 語句分開寫。

對於上面的案例,如果大家去掉第四步的 alter,那麼回滾是可以回滾成功的,這個小夥伴們自己來測試,我就不演示了。

當然 DDL 操作可不僅僅是 alter,其他的如 CREATE、DROP 等操作也會導致事務隱式提交,這裡松哥就不一一舉例了,小夥伴們可以自行嘗試。

2。 DCL 操作

DDL 和 DML 大家應該經常接觸到,但是 DCL 可能有小夥伴不清楚,DCL 其實就是 Data Control Language,中文譯作資料控制語言,我們日常授權或者回收資料庫上的許可權所使用的 GRANT、REVOKE 等,就算是 DCL 操作。

我舉個簡單例子:

咦,為什麼我的事務回滾不了

可以看到,跟第一小節的測試步驟一樣,只不過第四步換成一個 GRANT 語句,那麼最終的事務回滾也會失效,原因就在於事務已經提交了。

當然,除了 GRANT 和 REVOKE 之外,其他的建立、更新或者刪除使用者的操作也會導致事務隱式提交。主要有:

CREATE USER。。。DROP USER。。。ALTER USER。。。SET PASSWORD。。。

3。 新事務開啟

一個事務還沒提交,結果你又開啟了一個新的事務,那麼此時前一個事務也會隱式提交。看個例子:

咦,為什麼我的事務回滾不了

這個好理解,不多說。

4。 各種鎖操作

給表上鎖、解鎖也會導致事務隱式提交。如下:

咦,為什麼我的事務回滾不了

上鎖的 SQL 如 lock tables table_name read|write,會導致事務隱式提交,解鎖的 SQL 如 unlock tables 也會導致事務被隱式提交。

除了表鎖,一些全域性鎖如 FTWRL 也會導致事務的隱式提交,如下:

咦,為什麼我的事務回滾不了

5。 從機的操作

之前松哥有教大家如何大家 MySQL 主從:

MySQL8 主從複製踩坑指南

我們在從機上執行的一些操作如 start slave、stop slave、reset slave 以及 change master to 等語句也會隱式提交事務。

6。 其他表操作

其他的一下操作如重新整理許可權(flush privileges)、最佳化表(optimize table)、修復表(repair table)等操作,也會導致事務的隱式提交。

咦,為什麼我的事務回滾不了

咦,為什麼我的事務回滾不了

咦,為什麼我的事務回滾不了

我在網上看有人說 LOAD DATA 會隱式提交事務,松哥親測貌似並不會,如下圖:

咦,為什麼我的事務回滾不了

LOAD DATA 似乎並沒有導致事務隱式提交,歡迎大家提出不同見解一起探討。

7。 最佳實踐

那麼多隱式提交,我怎麼記得住呀?其實不用背,你只要記著事務裡只寫增刪改查(INSERT/DELETE/UPDATE/SELECT),就不會錯啦!