1. 程式人生 > >read uncommit, read commit, repeatable read, 共享鎖VS排他鎖

read uncommit, read commit, repeatable read, 共享鎖VS排他鎖

一般大家都對事務的四種隔離模式比較熟悉,從鬆到嚴依次是: - 讀取未提交(Read uncommitted):處於此模式下可能會出現髒讀、幻象讀、不可重複讀 - 讀取已提交(Read committed):處於此模式下可能會出現幻象讀、不可重複讀 - 可重複讀(Repeatable read):處於此模式下可能會出現幻象讀 - 序列(Serialize):不會出現幻象讀   那麼髒讀、幻象行、不可重複讀是什麼意思呢? - 髒讀:其它的事務(執行單個 select 語句也算一個事務)可以讀取到某個事務更新(包括插入和刪除)了但未提交的資料。髒讀是應用中應該避免的,因為讀取的是不可靠的資料(我覺得把這個叫做幻象行更形象,實際卻不是)。一般資料庫不會設定為這個模式,但有時候也會用到。髒讀的好處是讀取時不會對錶或記錄加鎖,可以繞開寫佇列的排隊,避免了等待。如在一個更新特別頻繁的表中要選擇表中所有的資料,就可以顯示指定隔離級別:
select .... at isolation 0   - 不可重複讀:這是描述在同一個事務中兩條一模一樣的 select 語句的執行結果的比較。如果前後執行的結果一樣,則是可重複讀;如果前後的結果可以不一樣,則是不可重複讀。這個特性從字面上也能看出來。      不可重複讀的模式下首先不會出現髒讀,即讀取的都是已提交的資料。在一個事務中,讀取操作是不會加排他鎖的,當下一條一模一樣的 select 語句的執行時,命中的資料集可能已經被其它事務修改了,這時候,還能讀到相同的內容嗎?      因此,要達到可重複讀的效果,資料庫需要做更多的事情,比如,對讀取的資料行加共享鎖,並保持到事務結束,以禁止其它事務修改它。這樣會降低資料庫的效能。而隔離級別的序列則比可重複讀更嚴格。一般資料庫的的隔離級別只設置到讀取已提交。這是兼顧了可靠性和效能的結果。
     上面還只提到了對命中的資料行加鎖,以防止其它事務修改它。但沒有提到,如果其它事務增加了符合條件的資料行怎麼辦?有些資料庫對這種情況新定義了兩個級別:讀取穩定性和遊標穩定性。前者不限制新增符合條件的資料行,而後者則阻止新增這樣的資料行。   - 幻象讀:是指兩次執行同一條 select 語句會出現不同的結果,第二次讀會增加一資料行,並沒有說這兩次執行是在同一個事務中。一般情況下,幻象讀應該正是我們所需要的。但有時候卻不是,如果開啟的遊標,在對遊標進行操作時,並不希望新增的記錄加到遊標命中的資料集中來。隔離級別為 遊標穩定性 的,可以阻止幻象讀。

------------------------------------- 資料庫中事務的 ACID 原則 原子性 (Atomicity): 事務的原子性是指一個事務中包含的一條語句或者多條語句構成了一個完整的邏輯單元,這個邏輯單元具有不可再分的原子性。這個邏輯單元要麼一起提交執行全部成功,要麼一起提交執行全部失敗。 一致性 (Consistency): 可以理解為資料的完整性,事務的提交要確保在資料庫上的操作沒有破壞資料的完整性,比如說不要違背一些約束的資料插入或者修改行為。一旦破壞了資料的完整性,SQL Server 會回滾這個事務來確保資料庫中的資料是一致的。 隔離性(Isolation): 與資料庫中的事務隔離級別以及鎖相關,多個使用者可以對同一資料併發訪問而又不破壞資料的正確性和完整性。但是,並行事務的修改必須與其它並行事務的修改相互獨立,隔離。 但是在不同的隔離級別下,事務的讀取操作可能得到的結果是不同的。 永續性(Durability): 資料持久化,事務一旦對資料的操作完成並提交後,資料修改就已經完成,即使服務重啟這些資料也不會改變。相反,如果在事務的執行過程中,系統服務崩潰或者重啟,那麼事務所有的操作就會被回滾,即回到事務操作之前的狀態。 我理解在極端斷電或者系統崩潰的情況下,一個發生在事務未提交之前,資料庫應該記錄了這個事務的"ID"和部分已經在資料庫上更新的資料。供電恢復資料庫重新啟動之後,這時完成全部撤銷和回滾操作。如果在事務提交之後的斷電,有可能更改的結果沒有正常寫入磁碟持久化,但是有可能丟失的資料會通過事務日誌自動恢復並重新生成以寫入磁碟完成持久化。
---------------------------------- 共享鎖【S鎖】 又稱讀鎖,若事務T對資料物件A加上S鎖,則事務T可以讀A但不能修改A,其他事務只能再對A加S鎖,而不能加X鎖,直到T釋放A上的S鎖。這保證了其他事務可以讀A,但在T釋放A上的S鎖之前不能對A做任何修改。 排他鎖【X鎖】 又稱寫鎖。若事務T對資料物件A加上X鎖,事務T可以讀A也可以修改A,其他事務不能再對A加任何鎖,直到T釋放A上的鎖。這保證了其他事務在T釋放A上的鎖之前不能再讀取和修改A。
---------------------------------- 總結:隔離模式(isolation)其實就是對讀寫加鎖的形象稱謂,應用在每個具體事務上。對資料庫本身而言,只有鎖的概念並沒有隔離模式的概念。當資料庫發現某個物件被加上共享鎖時,其他修改該物件的操作就被阻塞,直到該物件上的所有共享鎖都被釋放為止。