★ MYSQL隔離級別 通俗理解 + mysql、oracle默認事務隔離級別


 

★  臟讀    : 讀取了前一事務 未提交 的數據 ;

  不可重復讀    : 讀取了前一事務     提交 的數據;

★ 幻讀 與 不可重復讀     

  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改完后發現還有一條記錄沒有改過來,就好像發生了幻覺一樣.這就叫幻讀.

 

一下部分原文:https://blog.csdn.net/nanxiaotao/article/details/80412196 

1.事務的特性(ACID)

(1)原子性(Atomicity)。事務中所涉及的程序對數據庫的修改操作要么全部成功,要么全部失敗。

(2)一致性(Consistency)。事務執行前和執行后來源和去向保持平衡。

(3)隔離性(Isolation)。並發時每個事務是隔離的,相互不影響。

(4)持久性(Durubility)。一旦事務成功提交,應該保證數據的完整存在。
 

2.事務隔離級別

(1)read uncommitted 未提交讀    所有事務都可以看到沒有提交事務的數據。

  eg: 公司發工資了,領導把5000元打到A的賬號(正常工資2千)上,但是該事務並未提交,而A正好去查看賬戶,發現工資已經到賬,是5000元整,非常高興。

    但是領導隨后發現給A的工資發多了,於是迅速回滾了事務,修改金額后,將事務提交,最后A實際的工資只有2000元,A空歡喜一場。

  剖析:臟讀:“事務A:leader給A發工資”,

        “事務B:A查詢工資賬戶”,事務B讀取了事務A尚 uncommitted 的數據。當隔離級別設置為Read uncommitted時,就可能出現臟讀,如何避免臟讀,請看下一個隔離級別。

(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可串行化        強制的進行排序,在每個讀讀數據行上添加共享鎖。會導致大量超時現象和鎖競爭。這是花費最高代價但是最可靠的事務隔離級別。事務被處理為順序執行。除了防止臟讀,不可重復讀外,還避免了幻讀。

 

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');


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM