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 --
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70034820/viewspace-2994163/
,如需转载,请注明出处,否则将追究法律责任。