oracle中最严格的控制并发的两个特性:
Set transaction read only:
session1 | session2 |
set transaction read only name 'rxyu'; | |
select * from emp; | update emp set mgr_id=100 where emp_id=100; commit; |
begin dbms_lock.sleep(120); end; | |
select * from emp; | |
update emp set mgr_id=100 where emp_id=100; ORA-01456: may not perform insert/delete/update operation inside a READ ONLY transaction |
在这个例子中, transaction 'rxyu'始终能提供一致的结果(尽管在别的session中数据已经改变)。 不存在non-repeatable read, phantom read. 但作为代价, 在此事务中不用运行dml语句。 多用于报表。
Alter session set isolation_level=serializable:
session1 | session2 |
alter session set isolation_level=serializable; | |
select * from emp; | update emp set mgr_id=100 where emp_id=100; commit; |
begin dbms_lock.sleep(120); end; | |
select * from emp; | |
update emp set mgr_id=100 where emp_id=100; ORA-08177: can't serialize access for this transaction |
在这个例子中,在同一个事务中始终能提供一致的结果(尽管在别的session中数据已经改变)。 不存在non-repeatable read, phantom read. 但作为代价, 在session1的transacation开始后, 如果有别的session修改session1将要修改的数据, 就会发生ora-08177错误!但属于小概率事件。
值得注意的是:
a.因为修改的transaction发生在serializable和read only transaction之后, 因此这两种特性都要从rollback segment里度数据。 如果rollback segment设置的过小, 可能带来snapshot too old 错误。
b.如果从statment级来讨论这两个特性, 好像存在dirty read. 但如果从transaction级来看, 等同于read commited. 因此也有说法是这两种特性是oracle 把read commited 从statement级应用到了transaction 级而已。