Oracle事务隔离级别

一、事务四个性质(ACID)。
1、原子性(Atomaicity)
       一个事务是一个不可分割的单元。
2、一致性(Consistency)
      事务的原子性保证的事务的一致性。
3、隔离性(Isolation)
       三种现象:
       1)、脏读
                 即读出其它事务未提交的数据。
        2)、不可重复读
                  一个事务,两个不同时间,读取的数据不同,被他人更新了。
        3)、幻像读
                  一个事务,T1有一个查询结果集,T2再查询,数据变多了,他人有插入。
        根据以上三种现象,ANSI/ISO分为四种隔离级别:

隔离级别

脏读

不可重复读

幻像读

READ UNCOMMITTED

允许

允许

允许

READ COMMITTED

 

允许

允许

REPEATABLE READ

 

 

允许

SERIALIZABLE

 

 

 

 

READ UNCOMMITTED 提供非阻塞读 允许脏读。

READ COMMITTED 事务只能读取数据库中已经提交的数据,所以没有脏读,但可能有不可重复读和幻读(与事务早期相比,查询不光能看到其它提交事务更新的行,还能看到新插入的行),还有一点就是,如果在一条语句中查询了多行,除Oracle以外的其它数据库都可能   “退化”成像脏读一样,并且写阻塞读,产生等待,并且数据是错误的。

REPEATABLE READ(可重复读) 保证读一致(read-consistent) 在非Oracle数据库中

为达可重复读,需要阻塞一个事务,并且顺序执行两个事务,这是使用共亨锁来实现,这样,读会阻塞写,且写会阻塞读,影响并发性,而且会产生死锁。

SERIALIZABLE 就像一个用户一样地操作

上而说的都是非Oracle存在的缺点,在Oracle中有三个级别

Oracle实现原理:得用undo段实现数据多版本,来得到读一致性,并且支持非阻塞读,高并发性,鱼和熊掌兼得。

1)、READ COMMITTED 结果级别非上而提到的级别,不会脏读,不可重复读,幻读,这是Oracle默认的级别。

2)、READ ONLY(只读) 相当于无法在SQL完成任何修改的REPEATABLE READ或

SERIALIZABLE,唯一的区别是READ ONLY事务不行修改,因此没有去3)点中的ORA-08177错误,但他不能防止其它事务的修改,如果undo太小的话,有可能重用undo段,并导致ORA-15555:snaphot too old错误,所以设置足够大的undo大小。

3)、SERIALIZABLE  原本是语句级的读一致性,扩展到事务级,结果并非相对开始的那个时间点一致,而是在事务开始的那一刻就固定了,这是有代价的,只要你试图更新某一行,而这行自事务开始后已经修改,你就会得到ORA-08177 cant't serialize access for this transaction错误(同一块的所有行修改都可能导致这个错误)为避免这个错误,可以用select ... for update,实现串行访问,但这也并不意味是SERIALIZALBLE等同与串行顺序并且总能得到相同的结果。

 

时间

会话1执行

会话2执行

T1

alter session set isolation =_level = serializable

 

T2

 

alter session set isolation =_level = serializable

T3

Insert into a select count(*) from b

 

T4

 

Insert into a select count(*) from b

T5

commit

 

T6

 

commit

 

结果表a和表b都有一个为0的行

注意以sys用户或sysdba连接的用户不能有READ ONLY或SERIALIZABLE的事务。

4、持久性(Durability)
       就是数据持久化了,即数据已写入磁盘,数据不会再丢失。
二、事务的状态变迁图
1、活动状态
      在事务开始执行后,立即进入“活动”状态(Active),在活动状态,事务将执行对数据库的读/写操作,但是“写操作”并不写入磁盘,很可能暂时存放在系统的缓冲区中。
2、局部提交状态
        事务最后一语句执行之后,进入“局部提交”状态(Partially Committed)。
事务是执行完了,但是对数据库的修改,很可能还留在内存的系统缓冲区中,所以还不能说事务真正的结束,只能先进入局部提交状态。
3、失败状态
       处于活动的事务还没有到达最后一个语句就中止执行,此时称事务进入“失败”状态(Fialed)。或者处于局部提交状态的事务,遇到故障(如发生干扰,或未能完成对数据库的修改),也进入失败状态。
4、异常中止状态
      处于失败状态的事务,很可能已对磁盘中的数据库进行了一部分修改。为了保证事务的原子性,应该撤销(undo操作)该事务对数据库已作的修改。对事务的撤销操作称为事务的回退(rollback)。
     在Oracle中,先得用redo日志前滚事务,把在redo日志中标志已提交未和未提交的事务重做一遍,其中把未提交的数据利用redo日志中记录的undo信息回滚事务,这样保证的数据库事务的完整性,一致性。
     如何做到以上的恢复过程呢,有如下重要两点。
     1)、至少要等待相应修改的记录写入到redo日志中,才能允许事务往数据中写修改记录。
     2)、直到事务的所有修改记录都已经写到redo日志后,才能允许事务完成commit处理。
5、提交状态
       事务成功提交了,所以信息写入磁盘,持久化数据。
三、补充知识 点
       1)、一致读:再查询时,数据已修改,要从undo获取旧数据。
        2)、当前读:更新时,更新条件的字段已修改,由于读一致,要重新获取最新数
                  据。
        3)、写一致会导致重启动,条件字段有修改时,非条件字段修改不会。
        4)、 解发器想用:NEW和:OLD时,会比较一致读值和当前读值,并发现在二
                   者不同,会带来重启动。
         5)、不要在触发器里使用自治事务,自治事务不会因为重启动而回滚。
         6)、事务提交要以业务完成性,一致性为参照,并分析系统发现最大的事务是什
                   么,并设置相应的undo段大小,不要在循环中提交,导致数据不一致,因为
                   他可能导致:ORA-01555错误,使更新处于一种完全未知的状态,然是段太
 
 
 
 
 
 
 
 
 
 
 
 
 
                    小的话还好,但会产生:ORA-30036错误,但只要你设置足够大的undo
                    段,这个错误完成可以避免。
           7)、分布式事务中(2PC)时,可能会出现“可疑分布事务”,发生在,协调
                    结点收到所有结果投票提交事务结果时,要将结果发布给所以结点时,网络
                     中断时,这样要DBA手动提交“可疑分布事务”。
            8)、自动事可以做审计,Oracle的AUDIT也提供的这个能力。
            9)、决定事务大小的关键是数据的完整性。

猜你喜欢

转载自sqcwfiu.iteye.com/blog/2034228
今日推荐