search 2013 adfgs
作者:Sky.Jian | 可以任意转载, 但转载时务必以超链接形式标明文章原始出处 和 作者信息 及 版权声明
链接:http://isky000.com/database/%e5%86%8d%e7%9c%8bcommit%e4%b8%8erollback | del.icio.us | Twitter it

前面简要比较了Commit与Rollback所做的工作,说明了两者执行时间相差很大的原因,现在再细说一下各自在执行的时候的具体工作

还是先看看在整个事务过程中每一项工作的执行阶段吧
实际上在Commit之前,在数据库上面已经完成了将近99%的工作:
1、在SGA中产生了Rollback Segment
2、在SGA中记录了修改的数据块
3、在SGA中产生了1和2操作的Undo
4、一部分SGA中的数据(上面几点所产生的)已经记录到硬盘上(可能完成一部分也可能全部)
5、取得所有需要的Lock

然后如果Commit了:
6、首先当然是为此事务产生一个SCN(System change Number)
7、LGWR将上面4中可能没有完成的(在SGA中还没有来得及写入磁盘文件的)Redo Log信息数据继续完成(写入磁盘),并将6产生的SCN记录到Redo Log上面
8、DBWR检查LGWR是否完成7,然后将4中没有完成的(在SGA中没有来得及写入磁盘文件的)数据块的修改(如果有)写入数据文件
实际上到这里就是已经Commit(提交了)了
9、释放5中取得的所有Lock,释放前面被锁住的enqueued的等待的所有项目(如果有)
10、该寻找在此Transaction中被修改的所有块了,如果这些块还在Data Buffer中(还没有被DBWR写入数据文件),就通过快速模式来清理掉上面的Dirty信息(比如锁信息)。

从这里可以看出
Commit后所有的操作基本上没有涉及到数据库操作中最耗时间的I/O操作,所以需要的时间实际上是非常短的

如果执行Rollback:
6、通过从Rollback Segment中读取数据来撤销所有的已经做的修改,就是针对于前面所做操作的一个逆向操作(这里需要进行大量的I/O操作,比如读取Rollback Segment等等),当然包括对Redo Log的修改,同时这里的所有操作也都会记录到Redo Log中
7、释放5中取得的所有Lock,释放前面被锁住的enqueued的等待的所有项目(如果有)

所以Rollback操作涉及到大量的I/O操作
会耗用大量的时间

有些时候,我们的程序可能会收到:ORA-01555: snapshot too old错误,这也与Transaction中的Commit和Rollback有关。
造成这样的错误的主要原因其实是以下三种:
1、对于您的应用系统来说,Rollback Segment设置得太小以至于无法正常的完成工作(过早覆盖了需要保存的Rollback Segment内容)
2、应用系统中Fetch Across COMMITs,造成后面还需要访问的Rollback Segment中的内容被一个Commit操作给覆盖
3、数据块头部的Dirty信息(主要是指锁信息)没有及时的得到清理

具体的分析说明今天就不做了(得睡觉啦 :))

看完了要说点啥么?