防止01555错误的方法可以扩大undotbs,增大retention时间。 |
本帖最后由 oracle_lotus 于 2010-12-29 00:17 编辑 英文N多,好麻烦的! 经典的01555错误要从SCN说起吧,每个数据块的块头也有一个block scn,系统修改block时候会记录SCN。PS:oracle SCN无处不在,包括修改任何一个block! 加入一个事务预计要从8:00(假设8:00的current SCN为800)执行到8:10(同理8:10的current scn为810),比如银行统计8:00这个时刻的总账,虽然统计总账这个事务可以看成是一瞬间的,但实际上是要统计10min,如果在银行统计总账的期间,有session对账户余额进行了修改,这样就会导致读取的不一致,所以01555错误又可以理解为consistant read(一致性读)。 oracle 为了维护一致性原则,修改数据时候会将数据的前印象放到undotbs的某一个快,并且在undotbs记录SCN,所以当上面说到的统计事务读到修改过的块时,判断快的SCN是否大于统计事务的SCN,如果大于,就会根据SCN到undo空间读数据,一直读到scn小于或者等于统计事务发生之前的块为止。这样就维护了一致性读。 这点还可以参照snapshot的原理来理解! 简单点就是我要统计的是8:00这一个时刻的数据,但是统计量大不可能一瞬间完成,而在完成的时候会有人修改我要统计的数据,造成了我读取数据的不一致。 这是oracle内部维护一致性读的方法,同样也维护了并发原则就是当一个超级大的读取事务进行时候,数据可以被修改,而不是被你一个读取事务占用。 如果强制人工维护一致性读还可以给你要统计的表加个S锁。 lock table table_name in shared mode,这样也可以维护一致性读!这样就代价比较大,只能当你完成的读取事务别人才能修改表,没有好的并发! 个人认为oracle数据库的数据一致性原则是最高的原则,不知道正确与否? 有不对地方请您指出,修改。 |