在事务定义中,COMMIT操作和ROLLBACK操作的浸染是什么?
答案:COMMIT即提交,表示这个事务的所有操作都实行成功,COMMIT见告系统,数据库要进入一个新的精确状态,该事务对数据库的所有更新都要确保不因数据库的宕机而丢失。ROLLBACK即回退或回滚,表示事务中有实行失落败的操作,这些操作必须被撤销,ROLLBACK见告系统,已发生缺点,数据库可能处在禁绝确的状态,该事务对数据库的部分或所有更新必须被撤销。
在Oracle数据库中,COMMIT和ROLLBACK都属于事务掌握措辞(Transactional Control Language,TCL),TCL用于掩护数据的同等性,包括COMMIT、ROLLBACK、SAVEPOINT、ROLLBACK TO SAVEPOINT、SET TRANSACTION、SET CONSTRAINT等语句。个中,COMMIT语句用于确认和提交已经进行的数据库改变;ROLLBACK用于撤销已经进行的数据库改变;SAVEPOINT语句则用于设置保存点,以取消部分数据库改变,ROLLBACK命令会结束一个事务,但ROLLBACK TO SAVEPOINT不会;SET TRANSACTION设定一个事务的属性;SET CONSTRAINT指定是在每个DML语句之后、还是在事务提交后,实行可延迟完全性约束检讨。
对付保存点(SAVEPOINT),若有如下一段程序,则终极表EMPLOYEE中的数据如何呢?
CREATE TABLE EMPLOYEE(FIRST_NAME VARCHAR2(20),LAST_NAME VARCHAR2(25),SALARY NUMBER(8,2));
BEGIN
INSERT INTO EMPLOYEE(SALARY,LAST_NAME,FIRST_NAME) VALUES(35000,'WANG','FRED');
SAVEPOINT SAVE_A;
INSERT INTO EMPLOYEE(SALARY,LAST_NAME,FIRST_NAME) VALUES(40000,'WOO','DAVID');
SAVEPOINT SAVE_B;
INSERT INTO EMPLOYEE(SALARY,LAST_NAME,FIRST_NAME) VALUES(50000,'LDD','FRIK');
SAVEPOINT SAVE_C;
INSERT INTO EMPLOYEE(SALARY,LAST_NAME,FIRST_NAME) VALUES(45000,'LHR','DAVID');
INSERT INTO EMPLOYEE(SALARY,LAST_NAME,FIRST_NAME) VALUES(25000,'LEE','BERT');
ROLLBACK TO SAVEPOINT SAVE_C;
INSERT INTO EMPLOYEE(SALARY,LAST_NAME,FIRST_NAME) VALUES(32000,'CHUNG','MIKE');
ROLLBACK TO SAVEPOINT SAVE_B;
COMMIT;
END;
保存点(SAVEPOINT)是事务处理过程中的一个标志,与回滚命令(ROLLBACK)结合利用。其紧张用场是许可用户将某一段处理进行回滚而不必回滚全体事务,以上程序的处理过程为:
1)实行SAVEPOINT SAVE_A的时候创建了一个保存点SAVE_A;
2)实行SAVEPOINT SAVE_B的时候创建了一个保存点SAVE_B;
3)实行SAVEPOINT SAVE_C的时候创建了一个保存点SAVE_C;
4)在实行ROLLBACK TO SAVEPOINT SAVE_C后,SAVEPOINT SAVE_C到当前语句之间所有的操作都被回滚;也便是说回滚到了3)的状态;
5)在实行ROLLBACK TO SAVEPOINT SAVE_B后,SAVEPOINT SAVE_B到当前语句之间所有的操作都被回滚;也便是说回滚到了2)的状态;
6)在实行COMMIT后,只有SAVEPOINT SAVE_B之前的操作会被提交从而永久保存到数据库,以是表EMPLOYEE中的数据只有SALARY为35000和40000这两条数据。
那么,Oracle中的COMMIT操作都做了哪些事情呢?当完成事务操作,发出COMMIT命令之后,随后会收到一个反馈为“Commit complete.”,如下:
lhr@lhrdb> INSERT INTO EMP SELECT FROM EMP;
14 rows created.
lhr@lhrdb> COMMIT;
Commit complete.
提交完成(Commit complete),这个提示意味着Oracle已经将此韶光点之前的该事务产生的Redo日志从Redo Log Buffer写入了联机Redo日志文件(这个动作由后台进程LGWR完成),等这个日志写完成之后,Oracle就可以开释用户去实行其它任务。如果此后发生数据库崩溃,那么Oracle可以从Redo日志文件中规复这些提交过的数据,从而担保提交成功的数据不会丢失。
末了再来阐明一下,在Oracle中,无论事务大小,为什么COMMIT的相应韶光都相称“平”(即提交操作所花费韶光都非常短)?这是由于,在Oracle数据库中实行COMMIT之前,很多困难的、花费韶光的事情都已经做完了。例如,已经完成了以下操作:
l 已经在SGA中天生了Undo块。
l 已经在SGA中天生了已修正数据块。
l 已经在SGA中天生了对付前两项的缓存Redo。
l 取决于前三项的大小,以及这些事情花费的韶光,前面的每个数据(或某些数据)可能已经刷新输出到磁盘。
l 已经得到了所需的全部锁。
以是,在实行COMMIT时,余下的事情只是:
l 为事务天生一个SCN。
l 后台进程LGWR将所有余下的缓存Redo日志条款写到磁盘,并把SCN记录到联机Redo日志文件中。这一步便是真正的COMMIT。如果涌现了这一步,即已经提交,那么事务条款会从V$TRANSACTION中被删除,这解释该事务已经提交完成。
l V$LOCK中记录的会话所持有的锁,这些锁都将被开释,而排队等待这些锁的每一个其它会话都会被唤醒,可以连续完成它们的事情。
l 如果事务修正的某些块还在Buffer Cache中,那么会以一种快速的模式访问并“清理”,即快速块打消(Fast Commit Cleanout)。块打消(Block cleanout)是指打消存储在数据库块首部的与锁干系的信息,其本色是在打消块上的事务信息。
以是,在Oracle中,COMMIT操作可以确保提交成功的数据不丢失,而这个担保正是通过Redo来实现的。由此可以看到日志文件对付Oracle的主要,为了担保日志文件的安全,Oracle建议对Redo日志文件进行镜像。从Oracle 10g开始,如果设置了闪回规复区(Flash Recovery Area),那么Oracle缺省的就会对日志文件进行镜像。镜像的好处是当某个日志涌现问题,其余一个日志仍旧可用,可以担保数据不丢失,而且常日镜像存储于不同的硬盘,当某个存储涌现故障时,其余的存储可以用于担保镜像日志的安全。须要把稳的是,在Oracle中,COMMIT操作可以确保提交成功的数据不丢失,但是并不解释,提交了的数据都已经成功写入了磁盘数据文件中。
& 解释:
有关COMMIT的更多内容可以参考我的BLOG:http://blog.itpub.net/26736162/viewspace-2141922/