MySQL 隔離級別詳細解析
一、事務特性
1.原子性
事務是一個原子操作單元,事務中包含的所有操作要麼都做,要麼都不做,沒有第三種情況。
2.一致性
事務操作前和操作後都必須滿足業務規則約束,比如說A向B轉賬,轉賬前和轉賬後AB兩個賬戶的總金額必須是一致的。
3.隔離性
隔離性是資料庫允許多個併發事務同時對資料進行讀寫的能力,隔離性可以防止事務併發執行時由於交叉執行導致資料不一致的問題。
4.永續性
事務完成後,對資料的修改是永久的,即使出現系統故障也不會丟失。
二、併發問題
1.更新丟失
當兩個事務選擇同一行,然後更新資料,由於每個事務都不知道其他事務的存在,就會發生丟失更新的問題,(你我同時讀取同一行資料,進行修改,你commit之後我也commit,那麼我的結果將會覆蓋掉你的結果)。
2.髒讀
一個事務正在對一條記錄做修改,在這個事務提交之前,別的事務讀取到了這個事務修改之後的資料,也就是說,一個事務讀取到了其他事務還沒有提交的資料,就叫做髒讀。
3.不可重複讀
一個事務讀某條資料讀兩遍,讀到的是不一樣的資料,也就是說,一個事務在進行中讀取到了其他事務對舊資料的修改結果,(比如說 我開一個事務 修改某條資料 先查後改 執行修改動作的時候發現這條資料已經被別的事務刪掉了)
4.幻讀
一個事務中,讀取到了其他事務新增的資料,彷彿出現了幻象。(幻讀與不可重複讀類似,不可重複讀是讀到了其他事務update/delete的結果,幻讀是讀到了其他事務insert的結果)
三、隔離級別
1.未提交讀(read-uncommitted)
在一個事務中,可以讀取到其他事務未提交的資料變化,這種讀取其他會話還沒提交的事務,叫做髒讀現象,在生產環境中切勿使用。
2.已提交讀(read-committed)
在一個事務中,可以讀取到其他事務已經提交的資料變化,這種讀取也就叫做不可重複讀,因為兩次同樣的查詢可能會得到不一樣的結果。
3.可重複讀(repetable-read)
SQL/">MySQL預設隔離級別,在一個事務中,直到事務結束前,都可以反覆讀取到事務剛開始時看到的資料,並一直不會發生變化,避免了髒讀、不可重複讀現象,但是它還是無法解決幻讀問題。
4.可序列化(serializable)
這是最高的隔離級別,它強制事務序列執行,避免了前面說的幻讀現象,簡單來說,它會在讀取的每一行資料上都加鎖,所以可能會導致大量的超時和鎖爭用問題。
5.隔離級別一覽表
隔離級別 | 讀資料一致性 | 髒讀 | 不可重複讀 | 幻讀 |
未提交讀 | 最低級別,只保證不讀取物理上損壞的資料 | 有 | 有 | 有 |
已提交讀 | 語句級 | 無 | 有 | 有 |
可重複讀 | 事務級 | 無 | 無 | 有 |
可序列化 | 最高級別,事務級 | 無 | 無 | 無 |
隔離級別越嚴格,內部工作機制越複雜,較鬆散的隔離級別通常可以支援更高的併發。
四、個人分享
1.凡是涉及到表結構的語句,皆不受事務控制,嚴格的說,凡是DDL語句,都是自帶commit。比如create table 、alter table、truncate 等等
2.如果要確定出現了哪種併發問題,先查一下當前資料庫的隔離級別是什麼,再進行判斷。
-- 檢視當前資料庫的隔離級別
SHOW VARIABLES LIKE "%tx_isolation%"
Linux公社的RSS地址 :ofollow,noindex" target="_blank">https://www.linuxidc.com/rssFeed.aspx
本文永久更新連結地址:https://www.linuxidc.com/Linux/2018-11/155273.htm