mysql事務特點總結
1.mysql事務有4個隔離級別,以及會出現的問題如下圖:
2. 臟讀:
開啟事務A,B。事務A在還沒有提交的情況下,假如第一次查詢id=1的用戶的age=24。事務B執行了update 表 set age = 100 where id = 1; B事務並沒有提交,緊接著再次查詢id=1的用戶的age時,age變成了其他值,這時事務A中出現了臟讀。
解決辦法: 在事務中,讀取數據的時候加共享鎖。 select ... lock in share mode;
3. 不可重復讀:
什麽是不可重復讀?舉例說明,兩個事務A, B。兩個事務查詢結果都是id=1的用戶age=24,id=2的用戶age=25。這時A執行update 表 set age = 100 where id = 1; 這時A還沒有提交,B也沒有提交,B來查詢id=1的用戶age還是=24,然後A執行commit。此時B再次查詢id=1的用戶的age就=100,事務B並沒有重復讀取到之前id=1記錄的狀態。
不可重復讀和臟讀的區別就在於,修改了數據的事務有沒有執行commit。沒有提交,另一事務數據隔離性出現問題叫臟讀;提交了,另一事務數據隔離性出現問題叫不可重復讀。
解決辦法:給每個事務增加客戶端快照--可重復讀隔離級別。
4. 幻讀:
兩個事務A,B。兩個事務一開始 select * from ‘表‘ 查詢出來的數據都是一樣的,假如是5行記錄,把這時數據狀態稱為"數據狀態1"。這時,事務Ainsert一條記錄,然後commit。這時B查詢select * from ‘表‘,數據還是"數據狀態1",5行數據,然後執行update ‘表‘ set column=‘xxx‘,看下面返回的Rows matched: 會是6,比5行多一行!然後再執行select * from ‘表‘,返回了6行數據!多出了一行,好像之前5行的數據是幻覺一樣。這種情況,就叫幻讀。
解決辦法: mvcc,多版本控制,也叫樂觀鎖。
5.查看會話的隔離級別:
select @@global.tx_isolation;
6. 修改會話的隔離級別:
set tx_isolation=‘read-committed‘;
7. 可串行化隔離級別最高,通過對更改操作(cud)加排他鎖,查詢操作加共享鎖,沒有客戶端快照 來實現的。除了兩個事務都是執行的select操作,不阻塞另一事務外。其他交替出現的操作都會阻塞另一事務,知道該事務commit。
8. 如果一個事務A(任何隔離級別下)對某行記錄執行了更改操作,這時一個普通操作(非事務)也對該行記錄執行更改操作的化,會被阻塞,直到事務A commit.
mysql事務特點總結