大致记录一下SQL语句是如何执行的:
1. SELECT语句
首先,服务器进程会查看相应的数据块是否在database buffer cache中,若不是则将其复制过来。随后,在该会话的PGA中完成进一步的处理(如排序),最后将结果集返回给用户。
如果select的是一个在查询之后被其他会话改变了的数据,那么根据oracle的读一致性原则,服务器进程会进入undo段中定位原有数据。这样一来,在查询之后的任何数据变化(无论是否commit)都不可视。
经典的“ORA-1555:snapshot too old”错误就是由于原有数据不再位于撤销段中而导致的。
2. UPDATE语句
第一步,与select相同的是:确保要更改的数据块在内存中。不同的是:还需要一个undo段中的empty或expired数据块。
然后,会锁定相关数据记录和索引,接下来会在log buffer中生成数据块和撤销块的redo信息:要更新列的新值(用于数据块)和旧值(用于撤销块)都会被写入。
最后,用新值更新内存中的数据块,用旧值更新内存中的撤销块。
redo与undo不是一个互逆的过程!
3. INSERT与DELETE语句
开始几步与update类似,都要涉及到redo与undo。
区别在于生成的撤销数据量是不一样的:insert时,只需要在undo中记录下新行的rowid,这样在回滚时,oracle只需要一条delete from
4. ROLLBACK语句
回滚的机制就是利用撤销段中的数据,还原之前的数据操作:update对应update;insert对应delete;delete对应insert。
rollback也会生成相应的redo信息!
5. COMMIT语句
执行commit命令时,oracle只是让后台的LGWR进程将log buffer的内容写入到磁盘上的redo logfile中。此时的DBWn进程则完全没有任何操作!而不是像很多人以为的那样,DBWn会在commit时将脏数据块写回磁盘上的数据文件。
来自 “ ITPUB博客 ” ,链接:http://blog.itpub.net/13558130/viewspace-615932/,如需转载,请注明出处,否则将追究法律责任。

<%=items[i].content%>
<%if(items[i].items.items.length) { %><%=items[i].items.items[j].username%> 回复 <%=items[i].items.items[j].tousername%>: <%=items[i].items.items[j].content%>
转载于:http://blog.itpub.net/13558130/viewspace-615932/