丟失更新:兩個事務同時更新一行資料,最後一個事務的更新會覆蓋掉第一個事務的更新,從而導致第一個事務更新的資料丟失,這是由於沒有加鎖造成的;
1. 髒讀 :髒讀就是指當一個事務正在訪問資料,並且對資料進行了修改,而這種修改還沒有提交到資料庫中,這時,另外一個事務也訪問這個資料,然後使用了這個資料。
e.g.
1.Mary的原工資為1000, 財務人員將Mary的工資改為了8000(但未提交事務)
2.Mary讀取自己的工資 ,發現自己的工資變為了8000,歡天喜地。
3.而財務發現操作有誤,復原了事務,Mary的工資又變為了1000
像這樣,Mary記取的工資數8000是一個髒資料。
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 次讀出來的記錄數不一樣
參考:http://cupoy.iteye.com/blog/251796
http://blog.csdn.net/d8111/archive/2008/06/29/2595635.aspx
http://www.iteye.com/topic/332577
2、在一個程式中,依據事務的隔離等級將會有三種情況發生。
◆髒讀:一個事務會讀進還沒有被另一個事務提交的資料,所以你會看到一些最後被另一個交易回復掉的資料。
◆不可重複讀取:一個事務讀進一條記錄,另一個事務更改了這條記錄並提交完畢,這時候第一個事務再次讀這條記錄時,它已經改變了。
◆ 幻影讀:一個事務用Where子句來檢索一個表的資料,另一個事務插入一條新的記錄,並且符合Where條件,這樣,第一個事務用同一個where條件來檢索資料後,就會多出一條記錄。
3、資料庫提供了四種交易隔離等級, 不同的隔離等級採用不同的鎖類開來實現.
在四種隔離等級中, Serializable的層級最高, Read Uncommited層級最低.
大多數資料庫的預設隔離等級為: Read Commited,如Sql Server , Oracle.
少數資料庫預設的隔離等級為Repeatable Read, 如MySQL InnoDB儲存引擎
SQL SERVER鎖的機制
SQL server的所有活動都會產生鎖。鎖定的單元越小,就越能越能提高並發處理能力,但是管理鎖的開銷越大。如何找到平衡點,使並發性和效能都可接受是SQL Server的痛點。
SQL Server有如下幾種瑣:
SQL server的所有活動都會產生鎖。鎖定的單元越小,就越能越能提高並發處理能力,但是管理鎖的開銷越大。如何找到平衡點,使並發性和效能都可接受是SQL Server的痛點。
SQL Server有如下幾種瑣:
1、 共用鎖定
用於唯讀操作(SELECT),鎖定共用的資源。共用鎖定不會阻止其他使用者讀,但是阻止其他的使用者寫和修改。
2、 更新鎖定
更新鎖定是一種意圖鎖,當一個事務已經請求共用瑣後並試圖請求一個獨佔鎖的時候發生更新瑣。例如當兩個事務在幾行資料行上都使用了共用鎖定,並同時試圖擷取獨佔鎖以執行更新操作時,就發生了死結:都在等待對方釋放共用鎖定而實現獨佔鎖。更新鎖定的目的是只讓一個事務獲得更新鎖定,防止這種情況的發生。
3、 獨佔鎖
一次只能有一個獨佔鎖用在一個資源上,並且阻止其他所有的鎖包括共用縮。寫是獨佔鎖,可以有效防止’髒讀’。
4、 意圖縮
在使用共用鎖定和獨佔鎖之前,使用意圖鎖。從表的層次上查看意圖鎖,以判斷事務能否獲得共用鎖定和獨佔鎖,提高了系統的效能,不需從頁或者行上檢查。
5、 計劃鎖
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:
在資料表上放置了獨佔鎖定,以防止在事務完成之前由其他使用者更新行或向資料集中插入行,這是最嚴格的鎖。它防止了髒讀、不可重複讀取和幻象資料。
from: http://uule.iteye.com/blog/1109647