Mysql

在 InnoDB 中,事務是否意味著表的任何隱式鎖定?

  • January 9, 2017

隔離級別為 REPEATABLE_READ。

邏輯如下:

Transaction begins
Read data from Table A
If (Table A has Any Data) End Transaction and exit
If Table A has No Data, Proceed further
Delete a record in Table B
Transaction ends

現在,我的問題是關於以下場景:

  • 目前執行到達點#4。
  • 我有人在表 A 中插入數據(注意,目前執行在點 #4),這將在 #2 中返回一些結果。
  • 現在,目前執行將執行#5。它將刪除不應刪除的記錄。

事務中是否有任何隱式鎖定,或者我是否需要顯式鎖定表 A,以便在我送出更改之前沒有人可以在表 A 中插入任何數據?

在可重複讀取中,始終存在通過gen_clust_index(又名聚集索引)施加的行級鎖定。這就是交易的美妙之處。更有趣的是,InnoDB 有四種事務隔離級別,而不僅僅是一種:

您可以為 tx_isolation 設置四個值:

在您的特定情況下,將數據插入 TableA 實際上不會寫入磁碟。必要的更改記錄在三 (3) 個不同的位置:

  1. 記憶體中的日誌緩衝區
  2. 在 ibdata1
  • 撤消表空間
  • 回滾段
  • 雙寫緩衝區
  1. 在 ib_logfile0 或 ib_logfile1 中重做日誌資訊

這同樣適用於步驟 5 中的刪除。

執行回滾將撤消刪除,然後撤消插入。

你必須記住一些非常重要的事情:如果你想回滾多個 SQL 命令,你必須這樣開始:

SET autocommit = 0;
START TRANSACTION;

Transaction begins
Read data from Table A
If (Table A has Any Data) End Transaction (via ROLLBACK) and exit
If Table A has No Data, Proceed further
Delete a record in Table B
Transaction ends

COMMIT;

試一試 !!!

當每個人都在使用可重複讀取時

  • 您的 INSERT 只有您自己才能看到
  • 其他人的 DELETE 只有其他人才能看到

CAVEAT:對於 InnoDB,表級鎖定永遠不會隱含。如果要鎖定表,則必須LOCK TABLE顯式發出。

我做了一個關於鎖定的測試。我啟動了兩個連接,分別呼叫 A 和 B 來執行命令。操作流程列表如下。

  1. A:設置自動送出=0;
  2. A: update sometable set status = 0 where columns_a in(234,333) and is_del=0;
  3. B:設置自動送出=0;
  4. B:更新 sometable set status = 0 where columns_a in(222,444) and is_del=0;
  5. 答:送出;
  6. B:送出;

場景A:如果columns_a被設置為sometable的主鍵,第4步立即執行並結束。

場景B:如果columns_a 不是主鍵,但我們已經在sometable 的column_a 上添加了索引,則執行第4 步並立即完成。

場景C:如果columns_a被設置為sometable的主鍵,第4步立即執行並完成。

場景 D:如果 columns_a 不是主鍵,則第 4 步將等待鎖定,直到第 5 步執行。

我想知道“鎖”是否是表級鎖,在場景 D 中嘗試通過步驟 4 獲取。

引用自:https://dba.stackexchange.com/questions/18525