【實驗】Oracle的serializable隔離性級別影響
1.“事務隔離級別”有四種,每種都和“髒讀”、“不可重複讀”和“幻像讀”三個概念有關,請google自學
1)READ UNCOMMITTED
2)READ COMMITED
3)REPEATABLE READ
4)SERIALIZABLE
2.Oracle提供的“事務隔離級別”有上面的READ COMMITED(預設)和SERIALIZABLE外還有READ ONLY
這個可以透過下面的不正當的設定隔離級別的SQL語句的報錯資訊中得到
sec@ora10g> alter session set isolation_level=***;
alter session set isolation_level=***
*
ERROR at line 1:
ORA-02183: valid options: ISOLATION_LEVEL { SERIALIZABLE | READ COMMITTED }
看到了吧,有效的選項是SERIALIZABLE 或 READ COMMITTED。
3.READ COMMITTED級別是預設的,不深入討論,這裡我們實驗一下在SERIALIZABLE隔離級別下資料庫行為是什麼樣的
4.建立測試表test_serializable,並初始化兩條記錄
sec@ora10g> create table test_serializable (a number);
Table created.
sec@ora10g> insert into test_serializable values (1);
1 row created.
sec@ora10g> insert into test_serializable values (2);
1 row created.
sec@ora10g> commit;
Commit complete.
sec@ora10g> select * from test_serializable;
A
----------
1
2
5.重新進入sec使用者,並設定會話的隔離級別為SERIALIZABLE
sec@ora10g> conn sec/sec
Connected.
sec@ora10g> alter session set isolation_level=serializable;
6.另外開啟一個會話更新記錄並提交,注意這裡已經commit提交了修改
sec@ora10g> select * from test_serializable;
A
----------
1
2
sec@ora10g> update test_serializable set a=666 where a=1;
1 row updated.
sec@ora10g> commit;
Commit complete.
sec@ora10g> select * from test_serializable;
A
----------
666
2
7.重新回到第一個會話中,查詢表test_serializable記錄(在預設的READ COMMITED隔離級別應該能看到資料的變化)
sec@ora10g> select * from test_serializable;
A
----------
1
2
到這裡,可以發現表test_serializable中的記錄沒有任何的變化。
這就是SERIALIZABLE隔離級別的效果:
任何其他會話中的資料變更都不會在SERIALIZABLE隔離級別的會話中產生影響。
其實在執行alter session set isolation_level=serializable;設定隔離性級別後,這個會話中所有的查詢狀態就已經固定了。
這個在Oracle中是依靠undo技術來實現的,Oracle會在設定SERIALIZABLE隔離性級別後得到一個一致性的版本。
實驗到這裡就基本可以說明Oracle已經達到了SERIALIZABLE隔離級別的定義效果:不允許有“髒讀”,不允許有“不可重複讀”,不允許有“幻像讀”。
8.進一步,嘗試在SERIALIZABLE隔離級別的會話中重新更新這條資訊會得到什麼樣的效果呢,請看
sec@ora10g> update test_serializable set a=888 where a=1;
update test_serializable set a=888
*
ERROR at line 1:
ORA-08177: can't serialize access for this transaction
報錯資訊已經提示的很明顯了
原因:更新行已經在其他的會話中進行了修改,版本不一致
9.有沒有想嘗試更新一條沒有被“動過”的資料呢?看看下面的效果:
sec@ora10g> update test_serializable set a=888 where a=2;
1 row updated.
sec@ora10g> select * from test_serializable;
A
----------
1
888
sec@ora10g> commit;
Commit complete.
sec@ora10g> select * from test_serializable;
A
----------
666
888
有意思的現象出現了,不但沒有被“動過”的資料可以修改,而且在commit之後,第一行的記錄資訊也被重新整理成了最新的資料!想一想,這到底是為什麼呢?
10.小結
請見第7點內容
-- The End --
1)READ UNCOMMITTED
2)READ COMMITED
3)REPEATABLE READ
4)SERIALIZABLE
2.Oracle提供的“事務隔離級別”有上面的READ COMMITED(預設)和SERIALIZABLE外還有READ ONLY
這個可以透過下面的不正當的設定隔離級別的SQL語句的報錯資訊中得到
sec@ora10g> alter session set isolation_level=***;
alter session set isolation_level=***
*
ERROR at line 1:
ORA-02183: valid options: ISOLATION_LEVEL { SERIALIZABLE | READ COMMITTED }
看到了吧,有效的選項是SERIALIZABLE 或 READ COMMITTED。
3.READ COMMITTED級別是預設的,不深入討論,這裡我們實驗一下在SERIALIZABLE隔離級別下資料庫行為是什麼樣的
4.建立測試表test_serializable,並初始化兩條記錄
sec@ora10g> create table test_serializable (a number);
Table created.
sec@ora10g> insert into test_serializable values (1);
1 row created.
sec@ora10g> insert into test_serializable values (2);
1 row created.
sec@ora10g> commit;
Commit complete.
sec@ora10g> select * from test_serializable;
A
----------
1
2
5.重新進入sec使用者,並設定會話的隔離級別為SERIALIZABLE
sec@ora10g> conn sec/sec
Connected.
sec@ora10g> alter session set isolation_level=serializable;
6.另外開啟一個會話更新記錄並提交,注意這裡已經commit提交了修改
sec@ora10g> select * from test_serializable;
A
----------
1
2
sec@ora10g> update test_serializable set a=666 where a=1;
1 row updated.
sec@ora10g> commit;
Commit complete.
sec@ora10g> select * from test_serializable;
A
----------
666
2
7.重新回到第一個會話中,查詢表test_serializable記錄(在預設的READ COMMITED隔離級別應該能看到資料的變化)
sec@ora10g> select * from test_serializable;
A
----------
1
2
到這裡,可以發現表test_serializable中的記錄沒有任何的變化。
這就是SERIALIZABLE隔離級別的效果:
任何其他會話中的資料變更都不會在SERIALIZABLE隔離級別的會話中產生影響。
其實在執行alter session set isolation_level=serializable;設定隔離性級別後,這個會話中所有的查詢狀態就已經固定了。
這個在Oracle中是依靠undo技術來實現的,Oracle會在設定SERIALIZABLE隔離性級別後得到一個一致性的版本。
實驗到這裡就基本可以說明Oracle已經達到了SERIALIZABLE隔離級別的定義效果:不允許有“髒讀”,不允許有“不可重複讀”,不允許有“幻像讀”。
8.進一步,嘗試在SERIALIZABLE隔離級別的會話中重新更新這條資訊會得到什麼樣的效果呢,請看
sec@ora10g> update test_serializable set a=888 where a=1;
update test_serializable set a=888
*
ERROR at line 1:
ORA-08177: can't serialize access for this transaction
報錯資訊已經提示的很明顯了
原因:更新行已經在其他的會話中進行了修改,版本不一致
9.有沒有想嘗試更新一條沒有被“動過”的資料呢?看看下面的效果:
sec@ora10g> update test_serializable set a=888 where a=2;
1 row updated.
sec@ora10g> select * from test_serializable;
A
----------
1
888
sec@ora10g> commit;
Commit complete.
sec@ora10g> select * from test_serializable;
A
----------
666
888
有意思的現象出現了,不但沒有被“動過”的資料可以修改,而且在commit之後,第一行的記錄資訊也被重新整理成了最新的資料!想一想,這到底是為什麼呢?
10.小結
請見第7點內容
-- The End --
來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/519536/viewspace-611860/,如需轉載,請註明出處,否則將追究法律責任。
相關文章
- ORACLE的隔離級別Oracle
- serializable隔離級別下事務特性的幾個小測試
- Oracle的隔離級別(Isolation Level)Oracle
- oracle隔離級別深究追根Oracle
- Oracle-事務隔離級別Oracle
- MySQL的隔離級別MySql
- 資料庫事務隔離級別的深坑:預設值應修改為SERIALIZABLE資料庫
- spring事物屬性與隔離級別Spring
- Mysql 隔離級別MySql
- 3分鐘搞懂MySQL事務隔離級別及SET TRANSACTION影響事務MySql
- InnoDB 隔離模式對 MySQL 效能的影響模式MySql
- SqlServer事務詳解(事務隔離性和隔離級別詳解)SQLServer
- 檢視ORACLE事務隔離級別方法Oracle
- ORACLE資料庫事務隔離級別Oracle資料庫
- MySQL事務隔離級別的實現原理MySql
- 設定transaction的讀寫屬性與隔離級別
- MySQL事務的隔離級別MySql
- MySQL的事務隔離級別MySql
- MySQL 的隔離級別 自理解MySql
- Postgresql 的預設隔離級別SQL
- MySQL 事務隔離級別實現原理MySql
- Oracle資料庫事務隔離級別概述Oracle資料庫
- MySQL 事務隔離級別MySql
- PostgreSQL事務隔離級別SQL
- 事務、特性、隔離級別
- MySQL入門--隔離級別MySql
- MySQL設定隔離級別MySql
- 資料庫隔離級別資料庫
- MySQL事務隔離級別MySql
- [Mysql]事務/隔離級別MySql
- 事務系統的隔離級別
- 淺析MySQL InnoDB的隔離級別MySql
- Mysql資料庫的隔離級別MySql資料庫
- 理解mysql的事務隔離級別MySql
- SQL Server事務的隔離級別SQLServer
- MySQL 事務隔離級別解析和實戰MySql
- oracle事務隔離級別transaction isolation level初識Oracle
- 理解MySQL事務隔離級別MySql