MySQL事務隔離級別
-- SERIALIZABLE serializable 序列化 ;一個個事務排成序列的形式。事務一個挨一個執行,等待前一個事務執行完,后面的事務才可以順序執行
-- REPEATEABLE READ repeatable read 可重復讀 ;
-- READ COMMITED read committed 提交的可讀;(oracle默認)
-- READ UNCOMMITED read uncommitted 未提交的可讀;(mysql 默認)別的事務可以查看的到使用 當前事務還沒提交的 數據;會 臟讀,幻讀,不可重復讀。
mysql 的serializable序列化隔離級別所導致問題的模擬
首先,創建一張表來通過對該表的操作來實現
CREATE TABLE `software` (
`sid` int(11) DEFAULT NULL,
`version` int(11) DEFAULT NULL
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_0900_ai_ci
寫入一條記錄 insert into (sid,version) values (1,1);
同事開啟兩個事務 事務A 事務B;
1,創建第一個mysql連接,設置當前會話的隔離級別為 serializable;開啟一個事務A,查看software表中有一條記錄;
2.再創建一個新mysql連接,設置當前會話的隔離級別為 serializable;開啟一個事務B,查看software表中有一條記錄;
3.回到事務A的mysql會話中執行 向software表插入一條數據;
此時,事務A會執行失敗,提示超時了。失敗原因是,因為事務B也是serializable隔離級別的,並且還沒被提交。serializable隔離級別的多個事務不可以同事對同一張表修改!
4.事務B執行commit;
5.事務A重新執行插入一條記錄:insert into software (sid,version) values (2,1);
事務A此時執行成功了!
結論:serializable隔離級別的多個事務不可以同事對同一張表修改!
另外:當事務A執行的過程中如果對software表有update操作,事務B也不可以對事務A用到的表software表進行查詢操作!
1.事務A與事務B同時都只對software表做查詢 select 操作,不會導致死鎖,可以查詢出結果!
同時開啟事務A,事務B,然后執行查詢操作
1)事務A,
2)事務B,
3)事務A,
4)事務B,
2.事務A與事務B,都對software表做了查詢操作,則事務A或者事務B不可以對software做修改,插入的操作了,因為會出現死鎖的問題!
同時開啟事務A ,事務B ;然后執行查詢操作!
1)事務A
2)事務B
3)事務A
4)事務B
5)事務A
此時事務A對software執行update 或者 insert 操作 都會失敗, serializable 序列化 隔離級別,會造成表級鎖,對所有的記錄都不可以修改!
總結:在SERIALIZABLE級別下,不會使用mysql的mvcc機制,而是在每一個select請求下獲得讀鎖,在每一個update操作下嘗試獲得寫鎖。
只有當事務A將對表software的update操作,insert操作 commit之后, 事務B才能看到 事務A對表作出的修改!