髒讀、幻讀和不可重複讀 + 事務隔離級別

1. 髒讀 :髒讀就是指當一個事務正在訪問數據,而且對數據進行了修改,而這種修改尚未提交到數據庫中,這時,另一個事務也訪問這個數據,而後使用了這個數據。
 e.g.
        1.Mary的原工資爲1000, 財務人員將Mary的工資改成了8000(但未提交事務)
        2.Mary讀取本身的工資 ,發現本身的工資變爲了8000,歡天喜地!
        3.而財務發現操做有誤,回滾了事務,Mary的工資又變爲了1000
          像這樣,Mary記取的工資數8000是一個髒數據。html

2. 不可重複讀 :是指在一個事務內,屢次讀同一數據。在這個事務尚未結束時,另一個事務也訪問該同一數據。那麼,在第一個事務中的兩次讀數據之間,因爲第二個事務的修改,那麼第一個事務兩次讀到的的數據多是不同的。這樣在一個事務內兩次讀到的數據是不同的,所以稱爲是不可重複讀。
    e.g.
    1.在事務1中,Mary 讀取了本身的工資爲1000,操做並無完成
    2.在事務2中,這時財務人員修改了Mary的工資爲2000,並提交了事務.
    3.在事務1中,Mary 再次讀取本身的工資時,工資變爲了2000數據庫

 解決辦法:若是隻有在修改事務徹底提交以後才能夠讀取數據,則能夠避免該問題。併發

3. 幻讀 : 是指當事務不是獨立執行時發生的一種現象,例如第一個事務對一個表中的數據進行了修改,這種修改涉及到表中的所有數據行。同時,第二個事務也修改這個表中的數據,這種修改是向表中插入一行新數據。那麼,之後就會發生操做第一個事務的用戶發現表中還有沒有修改的數據行,就好象發生了幻覺同樣。
   e.g. 
   目前工資爲1000的員工有10人。
   1.事務1,讀取全部工資爲1000的員工。
   2.這時事務2向employee表插入了一條員工記錄,工資也爲1000
   3.事務1再次讀取全部工資爲1000的員工 共讀取到了11條記錄, 
 
 解決辦法:若是在操做事務完成數據處理以前,任何其餘事務都不能夠添加新數據,則可避免該問題高併發

不可重複讀的重點是修改 :
 一樣的條件, 你讀取過的數據,再次讀取出來發現值不同了
幻讀的重點在於新增或者刪除
 一樣的條件, 第 1 次和第 2 次讀出來的記錄數不同性能

 二、在一個程序中,依據事務的隔離級別將會有三種狀況發生。
  
  ◆髒讀:一個事務會讀進尚未被另外一個事務提交的數據,因此你會看到一些最後被另外一個事務回滾掉的數據。
  ◆不可重複讀:一個事務讀進一條記錄,另外一個事務更改了這條記錄並提交完畢,這時候第一個事務再次讀這條記錄時,它已經改變了
  ◆ 幻影讀:一個事務用Where子句來檢索一個表的數據,另外一個事務插入一條新的記錄,而且符合Where條件,這樣,第一個事務用同一個where條件來檢索數據後,就會多出一條記錄
 spa

三、數據庫提供了四種事務隔離級別, 不一樣的隔離級別採用不一樣的鎖類開來實現. 
在四種隔離級別中, Serializable的級別最高, Read Uncommited級別最低. 
大多數數據庫的默認隔離級別爲: Read Commited,如Sql Server , Oracle. 
少數數據庫默認的隔離級別爲Repeatable Read, 如MySQL InnoDB存儲引擎.net

   SQL SERVER鎖的機制 
   SQL server的全部活動都會產生鎖。鎖定的單元越小,就越能越能提升併發處理能力,可是管理鎖的開銷越大。如何找到平衡點,使併發性和性能均可接受是SQL Server的難點。
SQL Server有以下幾種瑣:
   SQL server的全部活動都會產生鎖。鎖定的單元越小,就越能越能提升併發處理能力,可是管理鎖的開銷越大。如何找到平衡點,使併發性和性能均可接受是SQL Server的難點。
SQL Server有以下幾種瑣:server

一、 共享鎖
用於只讀操做(SELECT),鎖定共享的資源。共享鎖不會阻止其餘用戶讀,可是阻止其餘的用戶寫和修改。htm

二、 更新鎖
更新鎖是一種意圖鎖,當一個事務已經請求共享瑣後並試圖請求一個獨佔鎖的時候發生更新瑣。例如當兩個事務在幾行數據行上都使用了共享鎖,並同時試圖獲取獨佔鎖以執行更新操做時,就發生了死鎖:都在等待對方釋放共享鎖而實現獨佔鎖。更新鎖的目的是隻讓一個事務得到更新鎖,防止這種狀況的發生。blog

三、 獨佔鎖
一次只能有一個獨佔鎖用在一個資源上,而且阻止其餘全部的鎖包括共享縮。寫是獨佔鎖,能夠有效的防止’髒讀’。

四、 意圖縮
在使用共享鎖和獨佔鎖以前,使用意圖鎖。從表的層次上查看意圖鎖,以判斷事務可否得到共享鎖和獨佔鎖,提升了系統的性能,不需從頁或者行上檢查。

五、 計劃鎖
Sch-M,Sch-S。對數據庫結構改變時用Sch-M,對查詢進行編譯時用Sch-S。這兩種鎖不會阻塞任何事務鎖,包括獨佔鎖。
讀是共享鎖,寫是排他鎖,先讀後更新的操做是更新鎖,更新鎖成功而且改變了數據時更新鎖升級到排他鎖

l     DEFAULT 使用數據庫設置的隔離級別 ( 默認 ) ,由 DBA 默認的設置來決定隔離級別 . 
l     READ_UNCOMMITTED 會出現髒讀、不可重複讀、幻讀 ( 隔離級別最低,併發性能高 ) 
l     READ_COMMITTED  會出現不可重複讀、幻讀問題(鎖定正在讀取的行) 
l     REPEATABLE_READ 會出幻讀(鎖定所讀取的全部行) 
l     SERIALIZABLE 保證全部的狀況不會發生(鎖表

ReadCommitted: 
假設A事務對正在讀取數據Data放置了共享鎖,那麼Data不能被其它事務改寫,因此當B事務對Data進行讀取時總和A讀取的Data數據是一致的,因此避免了髒讀。因爲在A沒有提交以前能夠對Data進行改寫,那麼B讀取到的某個值可能會在其讀取後被A更改從而致使了該值不能被重複取得;或者當B再次用相同的where字句時獲得了和前一次不同數據的結果集,也就是幻像數據。

ReadUncommitted:
假設A事務即不發佈共享鎖,也不接受獨佔鎖,那麼併發的B或者其它事務能夠改寫A事務讀取的數據,那麼併發的C事務讀取到的數據的狀態和A的或者B的數據均可能不一致,那麼。髒讀、不可重複讀、幻象數據均可能存在。

RepeatableRead:
(注意MSDN原文中的第一句話:在查詢中使用的全部數據上放置鎖,因此不存在髒讀的狀況)。
假設A事務對讀取的全部數據Data放置了鎖,以阻止其它事務對Data的更改,在A沒有提交以前,新的併發事務讀取到的數據若是存在於Data中,那麼該數據的狀態和A事務中的數據是一致的,從而避免了不可重複的讀取。但在A事務沒有結束以前,B事務能夠插入新記錄到Data所在的表中,那麼其它事務再次用相同的where字句查詢時,獲得的結果數可能上一次的不一致,也就是幻像數據。

Serializable:
 在數據表上放置了排他鎖,以防止在事務完成以前由其餘用戶更新行或向數據集中插入行,這是最嚴格的鎖。它防止了髒讀、不可重複讀取和幻象數據。

參考博客:

http://blog.sina.com.cn/s/blog_8020e4110101bfc6.html

http://cupoy.iteye.com/blog/251796

http://blog.csdn.net/d8111/archive/2008/06/29/2595635.aspx

http://www.iteye.com/topic/332577

http://www.cnblogs.com/kinghuhua/archive/2011/08/17/2142902.html 重點參考原文章

相關文章
相關標籤/搜索