事务隔离级别
1.脏读
当一个事务读取另一个事务尚未提交的修改时,产生脏读,在oracle中,不存在脏读.
2.不可重复读
在同一个事务中的同一个查询,如果因为别的事务修改或者删除,造成本事务查询的结果不一致.
3.幻读
在同一个事务中的同一个查询,因为别的事务添加,造成本事务查询的结果不一致.
temp表有14条数据
控制台1 删除014号数据
控制台2 删除013号数据
控制台2 commit
控制台1 查询数据为12条 013,014数据被删除
控制台2 查询数据为13条 013数据被删除
控制台1 commit
控制台1,2 查询数据为12条 013,014数据被删除
以上为两个控制台交互修改查询数据库,控制台1在进行中时,控制台2修改删除了数据,commit后,在控制台1可以发现数据被更新
可以发现并不是事务1开始执行语句(没有commit),事务2就必须等待事务1commit才可以DML操作.
Read Committed
Oracle缺省的设置是Read Committed隔离级别
保证不会出现脏读,但可能出现不可重复读和幻读.
Serializable
保证不会出现脏读,不可重复读和幻读.
在Serializable隔离级别,事务中的读取操作只能读取这个事务开始之前已经提交的数据结果。
Serializable 中的死锁
开始事务1,运行:
set transaction isolation level serializable;
select * from customer where State = 'CA'; --set tran语句隐式开始事务
得到1条记录,然后事务2开始运行:
set transaction isolation level serializable;
update customer set state = 'KO' where state = 'CA';
commit;
可以发现事务2立刻完成,没有阻塞。回到事务1继续:
select * from customer where State = 'CA';
update Customer set city = 'garden' where state = 'CA';
commit;
出现错误信息:
第 1 行出现错误:
ORA-08177: 无法连续访问此事务处理
总的来说,oracle利用多版本的方式实现串行化级别更少造成死锁,除非两个事务修改了相同的数据行,一般也不会造成冲突。
Read only
set transaction read only;
只读事务是指只允许执行查询的操作,而不允许执行任何其它dml操作的事务,使用只读事务可以确保用户只能取得某时间点的数据。假定机票代售点每天18点开始统计今天的销售情况,这时可以使用只读事务。在设置了只读事务后,尽管其它会话可能会提交新的事务,但是只读事务将不会取得最新数据的变化,从而可以保证取得特定时间点的数据信息。
例:有个机票代售系统,管理员要在每天18:00统计卖出多少票,但是在统计时,不能把该事务锁定,也就是别人还可以买票,这时就需要使用只读事务。
例:用户 system 登录,首先 set transaction read only; 用户 scott 登录,执行 select * from emp; 此时有14条记录,然后执行 insert into emp values (8888, 'skycloud', 'CLERK', 7900, to_date('1987-12-12', 'yyyy-mm-dd'), 500, 0, 10); 此时执行 select * from emp; 显示15条记录,但是用户 system 执行 select * from scott.emp; 仍然是14条记录。
设置事务的隔离级别:
Set Transaction Isolation Level Read Committed(默认)
Set Transaction Isolation Level Serializable(手动)
Set Transaction Read only;
作用周期为整个事务.
设置会话的隔离级别:
Alter Session Set Isolation_Level Read Committed
Alter Session Set Isolation_LevelSerializable