先看一張concepts中關於事務隔離級別的一張**:
從上圖可以看到:
通常事務的隔離級別定義為以下4種(基於3種在併發事務中需要避免的現象來劃分的):
1.read uncommitted
從字面意義可以看出,讀取那些未提交的資料。事務1在事務進行過程中,會讀到事務2修改了但是沒有提交的資料,所以產生了 髒讀(dirty read)。
2.read committed
讀取提交的資料。事務1在事務開始後第1次查詢了emp_id=1的emp_name=sean,然後事務2修改了emp_id=1的emp_name=king並提交,接著事務1第2次查詢emp_id=1的emp_name=king。可見在事務1的整個過程中,2次查詢同一條資料獲得了不同的結果,因為只要提交的資料就能被看到。所以這種隔離級別不能避免 不可重複讀(nonrepeatable read)。
3.repeatable read
字面意思是可以重複讀,比照上例,就是在事務1的整個過程中,查詢某一條資料總能獲得相同的結果。但是不能避免 幻讀(phantom read)。什麼是幻讀,和 不可重複讀 的區別在**?想象這種情形,事務1第1次統計dept_id=20的員工總數為50,此時事務2往員工表插入1條新的員工記錄並提交,事務1第2次查詢dept_id=20的員工總數為51.發現2次統計的結果不一致。這種情況稱之為 幻讀。與 不可重複讀的區別是,在此類場景中,事務1第1次讀取的資料並沒有被修改。而是新增了資料導致滿足條件的資料發生了變化。所以 幻讀 和 不可重複讀 的區別就在於事務讀取的資料是否發生了變化。
4.serializable
字面意思是序列化。在序列化隔離級別的時候,事務看到的都是事務開始那一刻的資料。舉例說明。現在員工表中dept_id=20的員工總數為50。事務1開始後,第1次查詢dept_id=20的員工總數為50,接著事務2刪除了1條dept_id=20的員工並提交,事務1第2次查詢dept_id=20的員工總數仍然為50(如果事務1隔離級別是2.read committed,此時結果就會是49),接著事務3增加了2條dept_id=20的員工並提交,事務1第3次查詢dept_id=20的員工總數仍然為50(如果事務1隔離級別是3.repeatable read,此時看到的結果是52,刪除屬於資料發生了變化,所以不可見,但是新增2條記錄可見)。序列化可以這麼理解,就是任何乙個事務都覺得資料庫就他乙個事務在序列執行,沒有其他事務和他並行執行,沒有其他事務,他看到的資料當然不會發生變化。
以上大致介紹了基於3種需要避免的現象而劃分出的4種隔離級別。
oracle支援 read committed(預設) 和 serializable 以及 read only(資料庫唯讀開啟,和serializable很像,但是禁止資料修改除非是sys使用者)。
隨著隔離級別的提高,資料庫對於事務併發的支援能力會下降。對於oracle預設情況下不能避免的 不可重複讀 和 幻讀 現象。在應用設計階段應該考慮到。
下面演示幾種場景:
--準備測試資料
sql> drop table t purge;
sql> create table t (id int);
sql> insert into t values(1);
sql> insert into t values(2);
sql> insert into t values(3);
sql> commit;
sql> select * from t;
id----------12
3--演示1、read committed(預設隔離級別)演示,所有以下操作按時間順序
--事務1 手動開啟乙個事務
sql> set transaction isolation level read committed;
--事務1 查詢表中資料
sql> select * from t;
id----------12
3--事務2 刪除一條資料並提交
sql> delete from t where id=3;
sql> commit;
--事務1 第2次查詢表中資料,發現和第1次讀取結果不一致,這就是 不可重複讀 現象。
sql> select * from t;
id----------12
--演示2、serializable(隔離級別)演示,所有以下操作按時間順序
--事務1 手動開啟乙個事務
sql> set transaction isolation level serializable;
sql> select * from t;
id----------12
--事務2 增加2條資料並提交
sql> insert into t select * from t;
sql> select * from t;
id----------12
12sql> commit;
--事務1 再次查詢表中資料,仍然只有2條資料,因為事務1在事務2之前開始,所以事務1只能看到的是事務開始那個時間的資料,其他都不可見
sql> select * from t;
id----------12
--演示3、ora-08177: can't serialize access for this transaction
--目前表中資料
sql> select * from t;
id----------12
3--事務1 手動開啟乙個事務
sql> set transaction isolation level serializable;
--事務2 修改1條資料先不提交
sql> update t set t.id=4 where id=3;
1 row updated.
--事務1 修改同一條資料
sql> update t set t.id=4 where id=3;
事務被hang住了
--事務2 提交剛剛的修改
sql> commit;
commit complete.
--事務1 產生報錯資訊,我們知道事務1先於事務2開啟,事務1開啟時,表中是存在id=3這條記錄的。當事務2修改這條記錄並提交。
--事務1再去修改這條記錄發現這條記錄發生了改變導致修改失敗。由此可見序列化的隔離級別併發性會大打折扣。
--前面我們說過,序列化就是事務覺得資料庫裡面就他乙個人在做操作,當他要修改乙個資料發現在事務開始後被別人修改了,就會報錯。
sql> update t set t.id=4 where id=3;
update t set t.id=4 where id=3
*error at line 1:
ora-08177: can't serialize access for this transaction
oracle®database
concepts
12c release 1 (12.1)
e41396-14
Oracle事務隔離級別
髒讀 dirty read 當乙個事務讀取另乙個事務尚未提交的修改時,產生髒讀。不可重複讀 nonrepeatable read 同一查詢在同一事務中多次進行,在此期間,由於其他事務提交了對資料的修改或刪除,每次返回不同的結果。幻讀 phantom read 同一查詢在同一事務中多次進行,由於其他提...
Oracle事務隔離級別
一 事務四個性質 acid 1 原子性 atomaicity 乙個事務是乙個不可分割的單元。2 一致性 consistency 事務的原子性保證的事務的一致性。3 隔離性 isolation 三種現象 1 髒讀 即讀出其它事務未提交的資料。2 不可重複讀 乙個事務,兩個不同時間,讀取的資料不同,被他...
oracle事務隔離級別 SERIALIZABLE
serializable 一般認為這是最受限的隔離級別,但是它也提供了最高程度的隔離性。serializable事務在乙個環境中操作時,就好像沒有別的使用者在修改資料庫中的資料一樣。我們讀取的所有行在重新讀取時都肯定完全一樣,所執行的查詢在整個事務期間也總能返回相同的結果。serializable這...