事務的四種隔離級別

事務具有ACID四種特性:

1、原子性(Atomicity):事務中的操作作爲一個原子操作,其要麼全部執行,要麼都不執行,不可以部分執行。比如銀行的轉賬服務,這個事務的最終結果一定是:某個賬戶的餘額增加了x,而另外一個賬戶的餘額減少了x,或者兩個賬戶的餘額未發生變化。而不會出現其他情況。

2、一致性(Consistent):在事務開始和完成時,數據都必須保持一致狀態。

3、隔離型(Isolation): 數據庫系統提供一定的隔離機制,保證事務不受外部併發操作的影響,在“獨立"的環境中運行,事務的中間狀態對外部不可見,反之亦然。比如轉賬過程中,用戶是不能查詢到一個賬戶餘額減少了,而另外一個賬戶餘額未發生變化的情況。

4、持久性(Durable):  事務完成之後,對數據的修改是永久的,即使系統故障也能保持。


事務處理中主要的問題:


1、更新丟失(Lost Update):當兩個或多個事務選擇同一行,然後基於最初選定的值更新該行時,由於每個事務都不知道其他事務的存在,就會發生丟失更新問題--最後的更新覆蓋了由其他事務所做的更新。
2、髒讀(Dirty Reads):一個事務正在對一條記錄做修改,在這個事務完成並提交前,這條記錄的數據就處於不一致狀態;這時,另一個事務也來讀取同一條記錄,如果不加控制,第二個事務讀取了這些“髒”數據,並據此做進一步的處理,就會產生對未提交的數據依賴關係。這種現象被形象地叫做"髒讀"。
3、不可重複讀(Non-Repeatable Reads):一個事務在讀取某些數據後的某個時間,再次讀取以前讀過的數據,卻發現其讀出的數據已經發生了改變、或某些記錄已經被刪除了。這種現象就叫做“不可重複讀”。
4、幻讀(Phantom Reads):一個事務按相同的查詢條件重新讀取以前檢索過的數據,卻發現其他事務插入了滿足其查詢條件的新數據,這種現象就稱爲“幻讀”。(網上大部分人說法)。在一個事務裏,查詢的結果都是事務開始時的狀態(保證了可重複讀),但是如果另一個事務同時提交了新數據,本事務再更新時,會”驚奇的“發現這些新數據,貌似之前看到的數據是”鬼影“一樣的幻覺。(部分的說法)。

不可重複讀關注點在讀取的數據本身的變化。 幻讀關注點在數據的集合的變化。


事務的隔離型

SQL2標準定義了四種隔離級別:

讀未提交(Read uncommitted):另一個事務修改了數據,但尚未提交,本事務中的SELECT可以讀取到這些未提交的數據(髒讀)

讀已提交(Read committed):本事務讀取到的是最新的數據(其他事務已經提交的數據都可讀取到)。但是導致的問題是同一個事務裏,前後兩次相同的SELECT讀取到的結果會不同(不可重複讀)。

可重複讀(Repeatable read):同一事務中,SELECT的結果是事務開始的時間點的狀態,同樣的SELECT操作讀取的結果是一致的。但是可能有幻讀現象。

可串行化(Serializable):讀操作也會隱式的獲取共享鎖,從而保證不同事務間的互斥性。

上述的四個級別依次增強。隔離級別越低,併發性能越好。

其中mysql InnoDB的默認隔離級別是可重複讀,利用MVCC提供一致性讀。


不同隔離級別下存在的問題如下:

隔離級

髒讀

不可重複讀

幻讀

讀未提交

(Read uncommitted)

可能

可能

可能

讀提交

(Read committed)

不可能

可能

可能

可重複讀

(Repeatable read)

不可能

不可能

可能

可串行化

(Serializable)

不可能

不可能

不可能


在Mysql的InnoDB引擎中,默認提供的可重複讀的隔離級別,可能會存在幻讀,但是可以通過next-key locking的策略避免幻讀。


  session1 session2
1 start transaction;  
2   start transaction;
3

select * from test where id > 17;


 
4  

insert into test(id,name,age,create_time) values(23,'test2',21,now());


5   commit
6

select * from test where id > 17;



 
7 update test set age = 23 where id > 17;  
8

select * from test where id > 17;


多出來一行記錄


 
9    

上述的問題可以通過使用select  for update來避免。 此時就涉及到mysql的相應的鎖機制的問題了,不在此展開了。



refer:

http://www.bitscn.com/pdb/mysql/201405/227973.html

http://bbs.csdn.net/topics/120024254

http://www.cnblogs.com/hustcat/archive/2009/10/18/1585626.html

http://dev.mysql.com/doc/refman/5.0/en/set-transaction.html#isolevel_repeatable-read

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章