兩個併發事務同時訪問資料庫表相同的行時,可能存在以下三個問題:
1、幻想讀:事務t1讀取一條指定where條件的語句,返回結果集。此時事務t2插入一行新記錄,恰好滿足t1的where條件。然後t1使用相同的條件再次查詢,結果集中可以看到t2插入的記錄,這條新紀錄就是幻想。
2、不可重複讀取:事務t1讀取一行記錄,緊接著事務t2修改了t1剛剛讀取的記錄,然後t1再次查詢,發現與第一次讀取的記錄不同,這稱為不可重複讀。
3、髒讀:事務t1更新了一行記錄,還未提交所做的修改,這個t2讀取了更新後的資料,然後t1執行回滾操作,取消剛才的修改,所以t2所讀取的行就無效,也就是髒資料。
一、為了處理這些問題,sql標準定義了以下幾種事務隔離級別:
read uncommitted 幻想讀、不可重複讀和髒讀都允許。乙個會話可以讀取其他事務未提交的更新結果,如果這個事務最後以回滾結束,這時的讀取結果就可能是不正確的,所以多數的資料庫都不會運用這種隔離級別。
read committed 允許幻想讀、不可重複讀,不允許髒讀。乙個會話只能讀取其他事務已提交的更新結果,否則,發生等待,但是其他會話可以修改這個事務中被讀取的記錄,而不必等待事務結束,顯然,在這種隔離級別下,乙個事務中的兩個相同的讀取操作,其結果可能不同。
repeatable read 允許幻想讀,不允許不可重複讀和髒讀。在乙個事務中,如果在兩次相同條件的讀取操作之間沒有新增記錄的操作,也沒有其他更新操作導致在這個查詢條件下記錄數增多,則兩次讀取結果相同。換句話說,就是在乙個事務中第一次讀取的記錄保證不會在這個事務期間發生改動。sql server是通過在整個事務期間給讀取的記錄www.cppcns.com加鎖實現這種隔離級別的,這樣,在這個lntcjaa事務結束前,其他會話不能修改事務中讀取的記錄,而只能等待事務結束,但是sql server不會阻礙其他會話向表中新增記錄,也不阻礙其他會話修改其他記錄。
serializable 幻想讀、不可重複讀和髒讀都不允許。在乙個事務中,讀取操作的結果是在這個事務開始之前其他事務就已經提交的記錄,sql server通過在整個事務期間給表加鎖實現這種隔離級別。在這種隔離級別下,對這個表的所有dml操作都是不允許的,即要等待事務結束,這樣就保證了在乙個事務中的兩次讀取操作的結果肯定是程式設計客棧相同的。sql標準所定義的預設事務隔離級別是serializable。
二、oracle中的隔離級別及實現機制:
oracle資料庫支援read committed 和 serializable這兩種事務隔離級別。所以oracle不支援髒程式設計客棧讀,即oracle中不允許乙個會話讀取其他事務未提交的資料修改結果,從而防止了由於事務回滾發生的讀取不正確。
oracle回滾段,在修改資料記錄時,會把這些記錄被修改之前的結果存入回滾段或撤銷段中。oracle讀取操作不會阻礙更新操作,更新操作也不會阻礙讀取操作,這樣在oracle中的各種隔離級別下,讀取操作都不會等待更新事務結束,更新操作也不會因為另乙個事務中的讀取操作而發生等待,這也是oracle事務處理的乙個優勢所在。
oracle預設的配置是read committed隔離級別(也稱為語句級別的隔離),在這種隔離級別下,如果乙個事務正在對某個表執行 dml操作,而這時另外乙個會話對這個表的記錄執行讀取操作,則oracle會去讀取回滾段或撤銷段中存放的更新之前的記錄,而不會象sql server一樣等待更新事務的結束。
oracle的serializable隔離級別(也稱為事務級別的隔離),事務中的讀取操作只能讀取這個事務開始之前已經提交的資料結果。如果在讀取時,其他事務正在對記錄執行修改,則oracle就會在回滾段或撤銷段中去尋找對應的原來未經修改的記錄(而且是在讀取操作所在的事務開始之前存放於回滾段或撤銷段的記錄),這時讀取操作也不會因為相應記錄被更新而等待。
設定隔離級別使用 set transaction isolation level [read uncommitted|read committed|repeatable read|serializable]
下面是oracle 設定serializable隔離級別乙個示例:
左面是事務t1,右面是事務t2,因為t2級別為serializable,所以即使事務t1在提交了資料之後,事務t2還是看不到t1提交的資料,幻想讀和不可重複讀都不允許了。
那如何能檢視到t1新增的記錄呢? 上面t1和t2是併發執行,在t1執行insert的時候事務t2已經開始了,因為t2級別是serializable,所以t2所查詢的數lntcjaa據集是t2事務開始前資料庫的資料。即事務t1在事務t2開始之後的insert和update操作的影響都不會影響事務t2。現在重新開啟乙個事務t3 就可以看到t1新增的記錄了。
當下列事件發生時,事務就開始了:
1、連線到資料庫,並執行第一條dml語句
2、前乙個事務結束後,又輸入了另一條dml語句
本文標題: oracle資料庫事務隔離級別介紹
本文位址:
ORACLE資料庫事務隔離級別
事務隔離級別 乙個事務對資料庫的修改與並行的另乙個事務的隔離程度。兩個併發事務同時訪問資料庫表相同的行時,可能存在以下三個問題 1 幻想讀 事務t1讀取一條指定where條件的語句,返回結果集。此時事務t2插入一行新記錄,恰好滿足t1的where條件。然後t1使用相同的條件再次查詢,結果集中可以看到...
ORACLE資料庫事務隔離級別
oracle資料庫事務隔離級別 事務隔離級別 乙個事務對資料庫的修改與並行的另乙個事務的隔離程度。兩個併發事務同時訪問資料庫表相同的行時,可能存在以下三個問題 1 幻想讀 事務t1讀取一條指定where條件的語句,返回結果集。此時事務t2插入一行新記錄,恰好滿足t1的where條件。然後t1使用相同...
ORACLE資料庫事務隔離級別
事務隔離級別 乙個事務對資料庫的修改與並行的另乙個事務的隔離程度。兩個併發事務同時訪問資料庫表相同的行時,可能存在以下三個問題 1 幻想讀 事務t1讀取一條指定where條件的語句,返回結果集。此時事務t2插入一行新記錄,恰好滿足t1的where條件。然後t1使用相同的條件再次查詢,結果集中可以看到...