轉至:
參考:★ mysql隔離級別 通俗理解 + mysql、oracle預設事務隔離級別
簡單點總結下他們的區別:髒讀是指讀取了未修改完的記錄,不可重複讀指因為被其它事務修改了記錄導致某事務兩次讀取記錄不一致,而幻讀是指因為其它事務對錶做了增刪導致某事務兩次讀取的表記錄數不一致問題。
(1)read uncommitted 未提交讀 所有事務都可以看到沒有提交事務的資料。
eg: 公司發工資了,領導把5000元打到a的賬號(正常工資2千)上,但是該事務並未提交,而a正好去檢視賬戶,發現工資已經到賬,是5000元整,非常高興。
但是領導隨後發現給a的工資發多了,於是迅速回滾了事務,修改金額後,將事務提交,最後a實際的工資只有2000元,a空歡喜一場。
剖析:髒讀:「事務a:leader給a發工資」,
(2)read committed 提交讀 事務成功提交後才可以被查詢到。
eg: a拿著工資卡去消費,出門前查到卡里是2000元,湊巧緊接著她的老婆作為急用把a工資卡的2000元轉到另一賬戶, 當a準備付款時,卻發現工資卡已經沒有錢,扣款失敗......
剖析:兩個併發的事務,「事務a:a消費」,
「事務b:a的老婆網上轉賬」,事務a事先讀取了資料,緊接著事務b更新了資料,並提交了事務,而事務a再次讀取該資料時,資料已經發生了改變。
當隔離級別設定為read committed時,避免了髒讀,但是可能會造成不可重複讀。
大多數資料庫的預設級別就是read committed,比如sql server , oracle。如何解決不可重複讀這一問題,請看下乙個隔離級別。
(3)repeatable 重複讀 同乙個事務內多次查詢卻返回了不同的資料值,即 可能將未提交的記錄查詢出來,而出現幻讀。注:mysql的預設隔離級別就是repeatable read。
前言:當隔離級別設定為repeatable read 時,可以避免不可重複讀。當a拿著工資卡去消費時,一旦系統開始讀取工資卡資訊(即事務開始),a的老婆就不可能對該記錄進行修改,也就是a的老婆不能在此時轉賬。
雖然repeatable read避免了不可重複讀,但還有可能出現幻讀 。
eg1: a的老婆在銀行工作,她可以很方便的檢視a的信用卡消費記錄。月末了,她正在查詢a當月的消費情況 (select sum(amount) from transaction where month = 『本月』)為80元,而a此時正好在某收銀台買單,
消費1000元,即新增了一條1000元的消費記錄(insert transaction ... ),並提交了事務,隨後a的老婆將a當月信用卡消費的明細列印到a4紙上,卻發現消費總額為1080元,a的老婆很詫異,以為出 現了幻覺,幻讀就這樣產生了。
eg2: 在事務a中,讀取到張三的工資為5000,操作沒有完成,事務還沒提交。
與此同時,事務b把張三的工資改為8000,並提交了事務。
隨後,在事務a中,再次讀取張三的工資,此時工資變為8000。在乙個事務中前後兩次讀取的結果並不致,導致了不可重複讀。(大部分資料庫預設的事物隔離級別都不會出現這種狀況)
(4)serializable可序列化 強制的進行排序,在每個讀讀資料行上新增共享鎖。會導致大量超時現象和鎖競爭。這是花費最高代價但是最可靠的事務隔離級別。事務被處理為順序執行。除了防止髒讀,不可重複讀外,還避免了幻讀。
附:
★ 髒讀 : 讀取了前一事務 未提交 的資料 ;
不可重複讀 : 讀取了前一事務 提交 的資料;
★ 幻讀 與 不可重複讀
common :都是讀取了另一條已經提交的事務(這點與髒讀不同);
differences :
不可重複讀 :查詢的都是同乙個資料項
幻讀 :針對的是一批資料整體(比如資料的個數)
不可重複讀eg: 《當隔離級別設定為repeatable read 時,可以避免不可重複讀>
eg2: 在事務a中,讀取到張三的工資為5000,操作沒有完成,事務還沒提交。
與此同時,事務b把張三的工資改為8000,並提交了事務。
隨後,在事務a中,再次讀取張三的工資,此時工資變為8000。在乙個事務中前後兩次讀取的結果並不致,導致了不可重複讀。(大部分資料庫預設的事物隔離級別都不會出現這種狀況)
幻讀eg:
eg1: 目前工資為5000的員工有10人,事務a讀取所有工資為5000的人數為10人。
此時,事務b插入一條工資也為5000的記錄,並且commit了。
這時,事務a再次讀取工資為5000的員工,記錄為11人。此時產生了幻讀。
(大部分資料庫預設的事物隔離級別都會出現這種狀況,此種事物隔離級別將帶來表級鎖)
eg2: a將db中all學生的score從數字分數改變為abcde等級,但是b就在此時插入了一條具體的分數,當a改完後發現還有一條記錄沒有改過來,就好像發生了幻覺一樣.這就叫幻讀.
預設隔離級別
mysql:
mysql預設的事務處理級別是'repeatable-read' -- 可重複讀
1.檢視當前會話隔離級別
select @@tx_isolation;
2.檢視系統當前隔離級別
select @@global.tx_isolation;
3.設定當前會話隔離級別
set session transaction isolatin level repeatable read;
4.設定系統當前隔離級別
set global transaction isolation level repeatable read;
oracle:
oracle資料庫支援read committed 和 serializable這兩種事務隔離級別。
預設系統事務隔離級別是read committed--- 讀已提交
1.檢視系統預設事務隔離級別,也是當前會話隔離級別
--首先建立乙個事務
declare
trans_id varchar2(100);
begin
trans_id := dbms_transaction.local_transaction_id( true );
end;
--檢視事務隔離級別
select s.sid, s.serial#,
case bitand(t.flag, power(2, 28))
when 0 then 'read committed'
else 'serializable'
end as isolation_level
from v$transaction t
join v$session s on t.addr = s.taddr and s.sid = sys_context('userenv', 'sid');
mysql事務詳解
使用者訪問資料庫時,資料庫會為使用者開啟乙個程序,使用者可以通過這個程序對資料庫進行增 刪 改 查的操作,這個程序就稱為事務。1 原子性 指事務是乙個不可分割的工作單位,事務中的操作要麼都發生,要麼都不發生 例如 在乙個事務中,對t1表新增乙個資料,並對t2表刪除乙個資料,這兩步操作要麼都成功,要麼...
MySQL 事務詳解
mysql 事務主要用於處理操作量大,複雜度高的資料。比如說,在人員管理系統中,你刪除乙個人員,你既需要刪除人員的基本資料,也要刪除和該人員相關的資訊,如信箱 文章等等,這樣,這些眾多的資料庫操作語句就構成乙個事務!一般來說,事務必須滿足以下 4 個條件 acid 而我們在學習事務的時候最複雜也是最...
Mysql事務詳解
不可重複讀和幻讀的區別應該在於 不可重複讀是主要是說多次讀取一條記錄,發現該記錄中某些列值被修改過。幻讀是主要是說多次讀取乙個範圍內的記錄 包括直接查詢所有記錄結果或者做聚合統計 發現結果不一致 標準檔案一般指記錄增多,記錄的減少應該也算是幻讀 解決不可重複讀的問題只需鎖住滿足條件的行,解決幻讀需要...