MySQL 事務隔離

邢闖洋發表於2021-05-24

前言

事務隔離,ACID(Atomicity、Consistency、Isolation、Durability,即原子性、一致性、隔離性、永續性)

事務隔離級別

  • 讀未提交是指,一個事務還沒提交時,它做的變更就能被別的事務看到。(read uncommitted)
  • 讀提交是指,一個事務提交之後,它做的變更才會被其他事務看到。(read committed)
  • 可重複讀是指,一個事務執行過程中看到的資料,總是跟這個事務在啟動時看到的資料是一致的。當然在可重複讀隔離級別下,未提交變更對其他事務也是不可見的。(repeatable read)
  • 序列化,顧名思義是對於同一行記錄,“寫”會加“寫鎖”,“讀”會加“讀鎖”。當出現讀寫鎖衝突的時候,後訪問的事務必須等前一個事務執行完成,才能繼續執行。(serializable)

例子說明

事務A 事務B
啟動事務,
查詢得到值1
啟動事務
查詢得到值1
將1改成2
查詢得到值V1
提交事務B
查詢得到值V2
提交事務A
查詢得到值V3
  • 若隔離級別是“讀未提交”, 則 V1 的值就是 2。這時候事務 B 雖然還沒有提交,但是結果已經被 A 看到了。因此,V2、V3 也都是 2。
  • 若隔離級別是“讀提交”,則 V1 是 1,V2 的值是 2。事務 B 的更新在提交後才能被 A 看到。所以, V3 的值也是 2。
  • 若隔離級別是“可重複讀”,則 V1、V2 是 1,V3 是 2。之所以 V2 還是 1,遵循的就是這個要求:事務在執行期間看到的資料前後必須是一致的。
  • 若隔離級別是“序列化”,則在事務 B 執行“將 1 改成 2”的時候,會被鎖住。直到事務 A 提交後,事務 B 才可以繼續執行。所以從 A 的角度看, V1、V2 值是 1,V3 的值是 2。

在 MySQL 中,實際上每條記錄在更新的時候都會同時記錄一條回滾操作。記錄上的最新值,透過回滾操作,都可以得到前一個狀態的值。

回滾日誌會在事務結束後沒有用到該回滾日誌後刪除

你可以使用以下語句來檢視超過60s的事務

select * from information_schema.innodb_trx where TIME_TO_SEC(timediff(now(),trx_started))>60
本作品採用《CC 協議》,轉載必須註明作者和本文連結

相關文章