當前位置:
首頁 > 最新 > 在事務定義中,COMMIT操作和ROLLBACK操作的作用是什麼?

在事務定義中,COMMIT操作和ROLLBACK操作的作用是什麼?

Q

題目如下所示:

在事務定義中,COMMIT操作和ROLLBACK操作的作用是什麼?

A

答案如下所示:

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中被刪除,這說明該事務已經提交完成。

lV$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/

喜歡這篇文章嗎?立刻分享出去讓更多人知道吧!

本站內容充實豐富,博大精深,小編精選每日熱門資訊,隨時更新,點擊「搶先收到最新資訊」瀏覽吧!


請您繼續閱讀更多來自 DBA寶典 的精彩文章:

TAG:DBA寶典 |