Mysql

TransactionA 所做的更改不會被 TransactionB 看到,即使 TransactionA 送出了這些更改。這怎麼可能?

  • December 21, 2017

即使第一個連接送出更改,2 個非並發連接是否有可能看到記錄的相同數據?

這是我從審核日誌中看到的範例:

ConnectionA starts TransactionA
   MasterRecordX gets locked for update.
   ...
   DetailRecordY is queried
   DetailRecordY is changed
   ...
ConnectionA commits TransactionA

---

ConnectionB starts TransactionB
   MasterRecordX gets locked for update.
   ...
   DetailRecordY is queried
   DetailRecordY is changed
   ...
ConnectionB commits TransactionB

問題是當在 TransactionB 上查詢 DetailRecordY 時,即使 MasterRecordX 在兩個事務開始時都被鎖定,它也看不到 TransactionA 所做的更改。

審計日誌還顯示 2 個請求是非並發的(一個和另一個之間大約一秒鐘)。

此外,在鎖定 MasteRecordX 之前不會查詢 DetailRecordY。數據庫是 mySQL,隔離級別是預設的 (REPETABLE READ)。

該問題與在 MasterRecordX 鎖定之前執行查詢有關。這是發生的事情:

ConnectionA starts TransactionA
RecordW is queried.
MasterRecordX gets locked for update.
...
       ConnectionB starts TransactionB
       RecordW is queried.
       MasterRecordX gets locked for update.
       ...
DetailRecordY is queried
DetailRecordY is changed
...
ConnectionA commits TransactionA
       DetailRecordY is queried
       DetailRecordY is changed
       ...
       ConnectionB commits TransactionB

因為在 DetailRecordY 更改並在 TransactionA 中送出之前查詢了 TransactionB 上的 RecordW,所以 TransactionB 看不到更改。由於隔離級別 (REPEATABLE READ),一旦在事務中執行查詢,就不會在該事務中看到以後的數據更改。

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