关于oracle commit
在oracle10gR2 中引入了commit 的write 子句,使我们对数据库的commit 操作的
控制能力提高了,同时也引入了对commit 语句理解的混乱,本文试图抛砖引玉,尽量
说明白oracle commit。(环境为oracle 11g R2)
commit_wait 初始化参数
oracle 默认commit 方式是wait ,也就是说等待LGWR写完redo 以后才向用户返回提交
完成的信息。我认为默认的方式在大多数情况下很好很简单。虽然oracle 默认的提交
方式是wait ,但是commit_wait 是没有默认值的。可以在系统级和会话级设置该参数。
该参数的作用是控制commit 的redo 信息写入redo logs 的方式。语法格式如下:
COMMIT_WAIT = { NOWAIT | WAIT | FORCE_WAIT }
nowait :该项是违反事务的ACID的,请慎用。可以在以下情况下考虑使用:
一、有大量的事务的redo 信息需要写入redo logs。
二、在实例崩溃的时候可以容忍部分数据的丢失。
三、等待LGWR 写对运用程序来说是不可以忍受的。
wait:oracle 默认的commit 方式,不需要显示指定。
force_wait:将会使用oracle 默认的提交方式。commit write wait;
commit_logging 参数
该参数没有默认值,可以在系统级或者会话级修改该参数。语法格式:
COMMIT_LOGGING = { IMMEDIATE | BATCH }
immediate :commit 语句会通过消息触发LGWR,因此redo 信息会立即的写入到redo logs.
batch: 写入到redo logs 的信息会被buffer 起来。如果commit_wait 参数设置成force_wait 以后改变commit_logging 参数,force_wait 选项不再有效。以上都是在系统级或者会话级控制commit 方式的行为,也可以在事务级控制commit 的行为。语句如下:
commit;
commit write wait;
commit write nowait;
commit write batch;
commit write immediate;
默认的情况下:commit = commit write wait = commit write immediate = commit write immediate wait;
小结:也许你会觉得wait 与immediate ,nowait 与 batch 是重复的,我对此的理解是:
wait 与 nowait 控制什么时候redo 信息写入到redo logs 。
immediate 与 batch 控制redo 信息以怎样的方式写入到redo logs。
nowait 方式的时候,redo 信息一放在redo buffer 就返回 Commit complete.然后以immediate 方式或者batch方式写入到redo logs。wait 方式的时候,把redo 信息放在redo buffer 以后需要等待LGWR写入,写入的方式可以是immediate 或者batch.nowait 的方式之所以有风险是因为,无法保证LGWR确实将redo 信息写入了redo logs ,不管用哪一种写入方式。因为redo 信息放置在redo buffer 以后不一定成功的写入到redo logs,比如还没有来得及写入到redo logs 服务器就掉电了等。nowait 可以提高事务的吞吐量,batch 可以降低IO 操作。但是伴随的风险就是破坏了事务的ACID,即已经提交成功的事务,不一定持久化到redo logs.
pl/sql 在非分布式事务下默认的提交方式是batch nowait.
commit_write 初始化参数在 oracle 11g 中已经弃用了,故没有讨论。