1. 程式人生 > 其它 >mysql事務級別及幻讀情況模擬

mysql事務級別及幻讀情況模擬

mysql是大家常用的關係型資料儲存資料庫,為了保證一組操作的原子性(同時成功/同時失敗)利用了事務。但是同一時間上讀寫可能存在的重複讀、幻讀/髒讀等問題,就涉及到事務級別(預設級別:RR 可重複讀 REPEATABLE-READ)設定。

事務級別分為:未提交可讀(read uncommitted) 提交可讀(read committed)可重複讀(repeatable read)序列化(Serializable)

read uncommitted:事務未提交時即可讀取,可能導致髒讀。

read committed:事務提交後才可讀取,但不可重複讀(更新事務未提交前,其它查詢為老值,但同一事務記憶體在更新前後查詢不一致問題)(發生在update操作時)。

repeatable read: 可重複讀,但是可能幻讀(發生在insert操作時)。

幻讀:A事務第一次查詢時只存在一條,B事務新增一條記錄,A事務再更新操作時更新成功兩條。

幻讀具體案例:

A事務:

SELECT * FROM `ims_user`;     #查詢結果1條

B事務:

INSERT ims_user ( NAME,STATUS) VALUES( 'c3',3);   #新插入一條
COMMIT ;

A事務:

SELECT * FROM `ims_user`;#查詢結果還是1條

UPDATE ims_user SET `status` = 4 WHERE `status`=3;  #更新結果2條。

COMMIT ;

幻讀產生可能原因分析:

1、結果快取:我們可以先插入,後查詢則結果正常。

驗證步驟:

B事務:

INSERT ims_user ( NAME,STATUS) VALUES( 'c3',3);   #新插入一條
COMMIT ;

 A事務:

              SELECT * FROM `ims_user`;#查詢結果正常,新插入資料可查詢到

                 2、無鎖:“SELECT * FROM `ims_user`;”查詢從快照中讀,不存在鎖。當發生“UPDATE/DELETE/INSERT”時為當前讀,會產生行鎖、表鎖或者間隙鎖(RR機制下)。

        解決方案:

             1、切換事務級別為Serializable。

             2、悲觀鎖:SELECT * FROM `ims_user` for update;

 

Serializable:序列化事務機制,序列處理任務。犧牲效能,保證資料。

其它:

檢視當前事務級別:SELECT @@tx_isolation;

檢視當前事務是否自動提交:show VARIABLES LIKE 'autocommit';