ORACLE提供了SQL92标准中的read committed和serializable,同时提供了非SQL92标准的read-only。
read committed: 这是ORACLE缺省的事务隔离级别。 事务中的每一条语句都遵从语句级的读一致性。 保证不会脏读;但可能出现非重复读和幻像。serializable: 简单地说,serializable就是使事务看起来象是一个接着一个地顺序地执行。仅仅能看见在本事务开始前由其它事务提交的更改和在本事务中所做的更改。 保证不会出现非重复读和幻像。 Serializable隔离级别提供了read-only事务所提供的读一致性(事务级的读一致性),同时又允许DML操作。 如果有在serializable事务开始时未提交的事务在serializable事务结束之前修改了serializable事务将要修改的行并进行了提交,则serializable事务不会读到这些变更,因此发生无法序列化访问的错误。(换一种解释方法:只要在serializable事务开始到结束之间有其他事务对serializable事务要修改的东西进行了修改并提交了修改,则发生无法序列化访问的错误.) 测试serializable的隔离机制:这里采用自治事务来测试(假设D表为空)需要在conmand窗口测试使用自治事务:根据SERIALIZABLE 的概念,只可以看到仅仅能看见在本事务开始前由其它事务提交的更改和在本事务中所做的更改。所以使用了该隔离级别,并使用了自治事务,将看不到插入的数据创建D表:
1 CREATE TABLE D(IDS VARCHAR2(100));
创建过程:使用自治事务
1 CREATE OR REPLACE PROCEDURE P2 IS 2 PRAGMA AUTONOMOUS_TRANSACTION; --自治事务 3 BEGIN 4 EXECUTE IMMEDIATE 'insert into d values(''a'')'; 5 COMMIT; 6 END;
测试语句:
1 ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE; 2 DECLARE 3 v_out_1 NUMBER; 4 PROCEDURE p(v_out OUT NUMBER) IS 5 BEGIN 6 SELECT COUNT(*) into v_out FROM d; 7 END; 8 BEGIN 9 p(v_out_1); 10 dbms_output.put_line('' || v_out_1); 11 p2; 12 p(v_out_1); 13 dbms_output.put_line('' || v_out_1); 14 NULL; 15 END;
结果分析:由于使用了serializable,和自治事务,
仅仅能看见在本事务开始前由其它事务提交的更改和在本事务中所做的更改。自治事务所做的插入无法查看到。创建过程:未使用自治事务:
1 CREATE OR REPLACE PROCEDURE P2 IS 2 --PRAGMA AUTONOMOUS_TRANSACTION; --自治事务 3 BEGIN 4 EXECUTE IMMEDIATE 'insert into d values(''a'')'; 5 COMMIT; 6 END;
--测试代码:
1 --测试语句 2 ALTER SESSION SET ISOLATION_LEVEL = SERIALIZABLE; 3 DECLARE 4 v_out_1 NUMBER; 5 PROCEDURE p(v_out OUT NUMBER) IS 6 BEGIN 7 SELECT COUNT(*) into v_out FROM d; 8 END; 9 BEGIN 10 p(v_out_1); 11 dbms_output.put_line('' || v_out_1); 12 p2; 13 p(v_out_1); 14 dbms_output.put_line('' || v_out_1); 15 NULL; 16 END;
结果分析:由于使用了serializable,但是未使用自治事务,
是在主事务中进行的插入操作。根据概念:仅仅能看见在本事务开始前由其它事务提交的更改和在本事务中所做的更改。他看到了自己的事务中的数据。-------------------------------------------------------------------------------------------在read committed模式下测试:总可以查询到提交的数据。