Oracle的隔離級別(Isolation Level)

Jujay發表於2011-10-08
剛剛回顧了事務的ACID特性,以前對隔離級別理解的不是很透徹,以為ACID中的Isolation和隔離級別(Isolation Level)有關,今天理清之後,發現這兩個是完全不同的概念。
ACID中的Isolation是指在一個事務的影響在其未提交前對其它事務時不可見的。這是所有的關係型資料庫必須要遵循的一個準則。
而每種資料庫產品的隔離級別的規定是不一樣的,比如Oracle就只有以下3種隔離級別:
隔離級別
描述
Read committed
(預設)
Each query executed by a transaction sees only data that was committed before the query (not the transaction) began.
Serializable Serializable transactions see only those changes that were committed at the time the transaction began, plus those changes made by the transaction itself through INSERT, UPDATE, and DELETE statements.

Read-only Read-only transactions see only those changes that were committed at the time the transaction began and do not allow INSERT, UPDATE, and DELETE statements.

下面這個例子可以很好的展示ACID中的Isolation以及以上3種隔離級別在Oracle是怎麼起作用的。
1. Isolation(獨立性)
這是資料庫天生具有的特性,不需要任何的配置。
1) 建立一個簡單的測試表:
SQL>create table test (id number);

Table created.

2) 在session1中插入一條資料:
Session1> insert into test values(1);

1 row created.

3) 在session2中查詢:
Session2> select * from test;

no rows selected

在session2中無法看到session1插入的資料,因為session1沒有提交,而根據事務獨立性的特性,未提交事務的影響在其它事務中是不可見的。

2. Read committed
這是Oracle預設的隔離級別,當一條語句開始執行時,它既能看到本事務之前對資料的影響,也能看到語句開始執行時已提交事務對資料的影響。
1) 清空測試表資料:
SQL> delete from test;

1 row deleted.

SQL> commit;

Commit complete.

2) 設定session1的隔離級別為Read committed:
Session1> alter session set isolation_level=read committed;

Session altered.

3) 在session1中插入一條資料:
Session1> insert into test values(1);

1 row created.
4) 在session1查詢:
SQL> select * from test;

        ID
----------
         1
在session1中可以看到本事務之前插入的資料。
5) 在session2中插入一條資料並提交:
Session2> insert into test values(2);

1 row created.

Session2> commit;

Commit complete.
6) 在session1中查詢:
Session1> select * from test;

        ID
----------
         2
         1
在session1中可以看到session2中已提交的資料。

3. Serializable
在Serializable的隔離級別中,只能看到本事務對資料的影響,而無法看到在本事務開始時未提交事務的影響。
1) 清空測試表資料:
SQL> delete from test;

2 rows deleted.

SQL> commit;

Commit complete.

2) 設定session1的隔離級別為Serializable:
Session1> alter session set isolation_level=serializable;

Session altered.
3) 在session1中插入資料:
Session1> insert into test values(1);

1 row created.
4) 在session1中查詢:
Session1> select * from test;

        ID
----------
         1
在session1中可以看到本事務之前插入的資料。
5) 在session2中插入一條資料並提交:
Session2> insert into test values(2);

1 row created.

SQL> commit;

Commit complete.
6) 在session1中查詢:
Session1> select * from test;

        ID
----------
         1

在session1中無法看到session2中插入的資料。

4. Read Only
在Read Only的隔離級別中,不允許INSERT, UPDATE和DELETE語句的出現,這種隔離級別很少用。
1) 清空測試表資料:
SQL> delete from test;

1 row deleted.

SQL> commit;

Commit complete.

2) 設定session1的隔離級別為Read Only:
Session1> SET TRANSACTION READ ONLY;

Transaction set.

3) 嘗試在session1中插入資料:
Session1> insert into test values(1);
insert into test values(1)
*
ERROR at line 1:
ORA-01456: may not perform. insert/delete/update operation inside a READ ONLY
transaction
插入資料出錯。

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/26277071/viewspace-708768/,如需轉載,請註明出處,否則將追究法律責任。

相關文章