在標準sql規範中,定義了4個事務隔離級別,不同的隔離級別對事務的處理不同:
◆未授權讀取(read uncommitted):允許髒讀取,但不允許更新丟失。如果乙個事務已經開始寫資料,則另外乙個資料則不允許同時進行寫操作,但允許其他事務讀此行資料。該隔離級別可以通過「排他寫鎖」實現。
◆授權讀取(read committed):允許不可重複讀取,但不允許髒讀取。這可以通過「瞬間共享讀鎖」和「排他寫鎖」實現。讀取資料的事務允許其他事務繼續訪問該行資料,但是未提交的寫事務將會禁止其他事務訪問該行。
◆可重複讀取(repeatable read):禁止不可重複讀取和髒讀取,但是有時可能出現幻影資料。這可以通過「共享讀鎖」和「排他寫鎖」實現。讀取資料的事務將會禁止寫事務(但允許讀事務),寫事務則禁止任何其他事務。
◆序列化(serializable):提供嚴格的事務隔離。它要求事務序列化執行,事務只能乙個接著乙個地執行,但不能併發執行。如果僅僅通過「行級鎖」是無法實現事務序列化的,必須通過其他機制保證新插入的資料不會被剛執行查詢操作的事務訪問到。
隔離級別越高,越能保證資料的完整性和一致性,但是對併發效能的影響也越大。對於多數應用程式,可以優先考慮把資料庫系統的隔離級別設為read committed,它能夠避免髒讀取,而且具有較好的併發效能。儘管它會導致不可重複讀、虛讀和第二類丟失更新這些併發問題,在可能出現這類問題的個別場合,可以由應用程式採用悲觀鎖或樂觀鎖來控制。
通過前面的介紹已經知道,通過選用不同的隔離等級就可以在不同程度上避免前面所提及的在事務處理中所面臨的各種問題。所以,資料庫隔離級別的選取就顯得尤為重要,在選取資料庫的隔離級別時,應該注意以下幾個處理的原則:
首先,必須排除「未授權讀取」,因為在多個事務之間使用它將會是非常危險的。事務的回滾操作或失敗將會影響到其他併發事務。第乙個事務的回滾將會完全將其他事務的操作清除,甚至使資料庫處在乙個不一致的狀態。很可能乙個已回滾為結束的事務對資料的修改最後卻修改提交了,因為「未授權讀取」允許其他事務讀取資料,最後整個錯誤狀態在其他事務之間傳播開來。
其次,絕大部分應用都無須使用「序列化」隔離(一般來說,讀取幻影資料並不是乙個問題),此隔離級別也難以測量。目前使用序列化隔離的應用中,一般都使用悲觀鎖,這樣強行使所有事務都序列化執行。
剩下的也就是在「授權讀取」和「可重複讀取」之間選擇了。我們先考慮可重複讀取。如果所有的資料訪問都是在統一的原子資料庫事務中,此隔離級別將消除乙個事務在另外乙個併發事務過程中覆蓋資料的可能性(第二個事務更新丟失問題)。這是乙個非常重要的問題,但是使用可重複讀取並不是解決問題的唯一途徑。
假設使用了「版本資料」,hibernate會自動使用版本資料。hibernate的一級session快取和版本資料已經為你提供了「可重複讀取隔離」絕大部分的特性。特別是,版本資料可以防止二次更新丟失的問題,一級session快取可以保證持久載入資料的狀態與其他事務對資料的修改隔離開來,因此如果使用對所有的資料庫事務採用授權讀取隔離和版本資料是行得通的。
「可重複讀取」為資料庫查詢提供了更好的效率(僅對那些長時間的資料庫事務),但是由於幻影讀取依然存在,因此沒必要使用它(對於web應用來說,一般也很少在乙個資料庫事務中對同乙個表查詢兩次)。
標準SQL規範中定義的四個事務隔離級別
在標準sql規範中,定義了4個事務隔離級別,不同的隔離級別對事務的處理不同 未授權讀取 read uncommitted 允許髒讀取,但不允許更新丟失。如果乙個事務已經開始寫資料,則另外乙個資料則不允許同時進行寫操作,但允許其他事務讀此行資料。該隔離級別可以通過 排他寫鎖 實現。授權讀取 read ...
標準SQL規範中定義的四個事務隔離級別
在標準sql規範中,定義了4個事務隔離級別,不同的隔離級別對事務的處理不同 隔離級別越高,越能保證資料的完整性和一致性,但是對併發效能的影響也越大。對於多數應用程式,可以優先考慮把資料庫系統的隔離級別設為read committed,它能夠避免髒讀取,而且具有較好的併發效能。儘管它會導致不可重複讀 ...
SQL標準之事務隔離的四個級別實現方式
級別 解釋讀未提交 read uncommitted 如果乙個事務已經開始寫資料,則另外乙個事務則不允許同時進行寫操作,但允許其他事務讀此行資料。讀已經提交的 read committed 讀取資料的事務允許其他事務繼續訪問該行資料,但是未提交的寫事務將會禁止其他事務訪問該行。可重複讀 repeat...