數據庫隔離級別

隔離級別

      當鎖定用作併發控制機制時,它可以解決併發問題。這使所有事務得以在彼此完全隔離的環境中運行,但是任何時候都可以有多個正在運行的事務。

可串行性是通過運行一組併發事務達到的數據庫狀態,等同於這組事務按某種順序連續執行時所達到的數據庫狀態。

 

      儘管可串行性對於事務確保數據庫中的數據在所有時間內的正確性相當重要,然而許多事務並不總是要求完全的隔離。例如,多個作者工作於同一本書的不同章節。新章節可以在任意時候提交到項目中。但是,對於已經編輯過的章節,沒有編輯人員的批准,作者不能對此章節進行任何更改。這樣,儘管有未編輯的新章節,但編輯人員仍可以確保在任意時間該書籍項目的正確性。編輯人員可以查看以前編輯的章節以及最近提交的章節。

      事務準備接受不一致數據的級別稱爲隔離級別隔離級別是一個事務必須與其它事務進行隔離的程度。較低的隔離級別可以增加併發,但代價是降低數據的正確性。相反,較高的隔離級別可以確保數據的正確性,但可能對併發產生負面影響。應用程序要求的隔離級別確定了 SQL Server 使用的鎖定行爲。

 

SQL-92 定義了下列四種隔離級別,SQL Server 支持所有這些隔離級別

  • 未提交讀(事務隔離的最低級別,僅可保證不讀取物理損壞的數據)。

  • 提交讀(SQL Server 默認級別)。

  • 可重複讀。

  • 可串行讀(事務隔離的最高級別,事務之間完全隔離)。

如果事務在可串行讀隔離級別上運行,則可以保證任何併發重疊事務均是串行的。

下面四種隔離級別允許不同類型的行爲。

隔離級別髒讀不可重複讀取幻像
未提交讀(Read UnCommited)
提交讀(Read Commited)
可重複讀(Repeatable Read)
可串行讀(Serialiazable)


事務必須運行於可重複讀或更高的隔離級別以防止丟失更新。當兩個事務檢索相同的行,然後基於原檢索的值對行進行更新時,會發生丟失更新。如果兩個事務使用一個 UPDATE 語句更新行,並且不基於以前檢索的值進行更新,則在默認的提交讀隔離級別不會發生丟失更新

 

------------------------------------------------------

 

PS:以上摘自SQL Server聯機文檔

       大部分關係數據庫採用 提交讀 的隔離級別,MySQL數據庫採用 可重複讀 的隔離級別

 

------------------------------------------------------

 

MySQL查詢和修改隔離級別語句:

       查詢:select @@tx_isolation;

       修改:set transation isolation level read uncommited;--//將數據庫的隔離級別修改爲 未提交讀。

 

------------------------------------------------------

名詞解釋:

 

       髒讀:一個事務讀到另一個事務,尚未提交的修改,就是髒讀。這裏所謂的修改,除了Update操作,不要忘了,還包括
Insert和Delete操作。髒讀的後果:如果後一個事務回滾,那麼它所做的修改,統統都會被撤銷。前一個事務讀到的數據,就是垃圾數據。

 

舉個例子:預訂房間。
       有一張Reservation表,往表中插入一條記錄,來訂購一個房間。

 

          事務1:在Reservation表中插入一條記錄,用於預訂99號房間。

 

          事務2:查詢,尚未預定的房間列表,因爲99號房間,已經被事務1預訂。所以不在列表中。

 

          事務1:信用卡付款。由於付款失敗,導致整個事務回滾。


          所以插入到Reservation 表中的記錄並不置爲持久(即它將被刪除)。

 

       現在99號房間則爲可用。


       所以,事務2所用的是一個無效的房間列表,因爲99號房間,已經可用。如果它是最後一個沒有被預定的房間,那麼這將是一個嚴重的失誤。

 

       注:髒讀的後果很嚴重。

 

       不可重複讀:在同一個事務中,再次讀取數據時【就是你的select操作】,所讀取的數據,和第1次讀取的數據,不一樣了。就是不可重複讀。如果,數據庫系統的隔離級別。允許,不可重複讀。那麼你啓動一個事務,並做一個select查詢操作。查詢到的數據,就有可能,和你第2次,3次...n次,查詢到的數據不一樣。一般情況下,你只會做一次,select查詢,並以這一次的查詢數據,作爲後續計算的基礎。因爲允許出現,不可重複讀。那麼任何時候,查詢到的數據,都有可能被其他事務更新,查詢的結果將是不確定的。

 

舉個例子:
 事務1:查詢有雙人牀房間。99號房間,有雙人牀。

 

 事務2:將99號房間,改成單人牀房間。

 

 事務1:再次執行查詢,請求所有雙人牀房間列表,99號房間不再列表中了。也就是說,
               事務1,可以看到其他事務所做的修改。


在不可重複讀,裏面,可以看到其他事務所做的修改,而導致2次的查詢結果不再一樣了。
這裏的修改,是提交過的。也可以是沒有提交的,這種情況同時也是髒讀。

 

       幻讀:事務1讀取指定的where子句所返回的一些行。然後,事務2插入一個新行,這個新行也滿足事務1使用的查詢where子句。然後事務1再次使用相同的查詢讀取行,但是現在它看到了事務2剛插入的行。這個行被稱爲幻象,因爲對事務1來說,這一行的出現是不可思議的。

舉個例子:
      事務1:請求沒有預定的,雙人牀房間列表。


      事務2:向Reservation表中插入一個新紀錄,以預訂99號房間,並提交。


      事務1:再次請求有雙人牀的未預定的房間列表,99號房間,不再位於列表中。

 

      注:幻讀,針對的是,Insert操作。如果事務2,插入的記錄,沒有提交。那麼同時也是髒讀。

 

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