Mysql
TransactionA 所做的更改不會被 TransactionB 看到,即使 TransactionA 送出了這些更改。這怎麼可能?
即使第一個連接送出更改,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),一旦在事務中執行查詢,就不會在該事務中看到以後的數據更改。