oracle事务_笔记4:COMMIT的WRITE扩展
COMMIT的WRITE扩展
在Oracle Database 10g Release 2及以上版本中,可以为COMMIT语句增加一个WRITE子句。这个WRITE子句允许等到生成的redo写至磁盘之后再提交(WAIT,这是默认选项),或者不等待写redo就直接提交(NOWAIT)。NOWAIT选项是一个新功能,这个功能必须谨慎使用。
通常情况下,COMMIT是一个同步过程。应用首先调用COMMIT,然后等待整个COMMIT处理完成。在Oracle Database 10g Release 2之前,所有Oracle数据库版本支持的都是这种COMMIT行为,这也是Oracle Database 10g Release 2及以上版本的默认行为。
在Oracle的当前版本中,并不需要等待提交完成(这需要一定的时间,因为提交涉及一个物理I/O操作,要向存储在磁盘上的redo日志文件完成物理写操作),可以在后台完成提交。这会带来一个副作用:提交不能保证持久性。也就是说,应用可能会从数据库得到一个响应,指出已经收到你的异步提交,而且其他会话能够看到你作出的改变,不过后来却发现你原以为已经提交的事务实际上并未真正提交。这种情况很少见,往往涉及严重的硬件或软件故障。要让一个异步提交不具有持久性,数据库必须异常关闭,这意味着数据库实例或运行这个数据库实例的计算机必须完全失效。
那么,既然事务要保证持久性,这种可能导致非持久性的特性又有什么用呢?答案在于性能。在应用中发出一个COMMIT时,会请求LGWR进程得到生成的redo,并确保将生成的这些redo写至在线redo日志文件。完成物理I/O操作的速度相当慢(这里就涉及物理I/O),因为相对来讲,将数据写至磁盘会花费很长时间。所以,COMMIT甚至比事务中DML语句本身耗费的时间还要长!如果异步完成COMMIT,就不再需要等待客户应用中的物理I/O,这会让客户应用速度更快,特别是如果有大量COMMIT,异步提交会让速度大大提高。
在什么情况下需要使用这个新功能,从而不必等待就直接提交呢?
.定制的数据加载程序。程序必须是定制的,因为它要有一些额外的逻辑,以便处理遭遇系统失败时提交无法持久存储的问题。
.处理某种实况数据提要的应用(比如说股市的股票报价数据提要),这些应用会向数据库中插入大量时间敏感的信息。数据库离线时数据流仍继续保持,系统故障期间生成的数据不会进行处理。这些数据不做处理是可以接受的,因为股票数据具有时间敏感性,几秒之后老数据就会被新数据覆盖。
.应用实现了自己的“排队”机制,例如某个应用可能把数据存储在一个包含PROCESSED_FLAG列的数据库表中。新数据到来时,会随之插入值PROCESSED_FLAG='N'(表示未做处理)。另外,再实现一个例程,它的任务是读取PROCESSED_FLAG='N'的记录,完成某个快速的小事务,并把PROCESSED_FLAG='N'改为'Y'。如果提交之后(由于某个系统故障)未能成功完成提交也没有关系,因为只需要让处理这些记录的过程再对记录做一次处理(把PROCESSED_FLAG='Y'改回为'N'),即是“可重启的”。
查看这几类应用时,你会注意到这3种应用都是后台的非交互式应用,它们不会与人直接交互。如果应用需要与人交互,向用户报告“提交完成”,就应当使用同步提交。对于面向客户的在线应用,不能把异步提交作为改善性能的手段。
异步提交只适用于面向批处理的应用,也就是那些出现故障时能自动重启的应用。交互式应用在出现故障时无法自动重启,必须由人来重新执行事务。因此,确定是否可以使用这个功能时,还可以考虑一个“标志”——这是一个批处理还是交互式应用?除非是面向批处理的,否则都应当采用同步提交。
本文来源 我爱IT技术网 http://www.52ij.com/jishu/5236.html 转载请保留链接。
- 评论列表(网友评论仅供网友表达个人看法,并不表明本站同意其观点或证实其描述)
-
