該信息應該很容易找到,但我沒有任何運氣。BEGIN - END PL/SQL中的塊原子事務
當我在PL/SQL中有一個BEGIN - END
塊時,它是否表現爲原子事務,它會嘗試在點擊END
塊時提交,如果出現任何問題,請回滾更改?
如果不是,我該如何確保BEGIN-END塊內的代碼的行爲類似於原子事務,並且該塊如何在默認情況下運行?
編輯:我從一個存儲過程運行,我使用一個隱式塊,我想。
該信息應該很容易找到,但我沒有任何運氣。BEGIN - END PL/SQL中的塊原子事務
當我在PL/SQL中有一個BEGIN - END
塊時,它是否表現爲原子事務,它會嘗試在點擊END
塊時提交,如果出現任何問題,請回滾更改?
如果不是,我該如何確保BEGIN-END塊內的代碼的行爲類似於原子事務,並且該塊如何在默認情況下運行?
編輯:我從一個存儲過程運行,我使用一個隱式塊,我想。
首先,BEGIN..END
僅僅是句法元素,與交易無關。其次,在Oracle中,所有單獨的DML語句都是原子的(即它們要麼全部成功,要麼在第一次失敗時回滾任何中間變更)(除非使用EXCEPTIONS INTO選項,這裏我不會介紹) 。
如果你想一組被視爲單個原子事務的語句,你會做這樣的事情:
BEGIN
SAVEPOINT start_tran;
INSERT INTO .... ; -- first DML
UPDATE .... ; -- second DML
BEGIN ... END; -- some other work
UPDATE .... ; -- final DML
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO start_tran;
RAISE;
END;
這樣一來,任何異常都會使報表在此塊被軋返回,但在此塊之前運行的任何語句都不會回滾。
請注意,我不包含COMMIT - 通常我更喜歡調用過程來發出提交。
這是事實,沒有例外處理程序BEGIN..END塊將自動處理此爲您提供:
BEGIN
INSERT INTO .... ; -- first DML
UPDATE .... ; -- second DML
BEGIN ... END; -- some other work
UPDATE .... ; -- final DML
END;
如果拋出一個異常,所有的插入和更新將回滾;但只要你想添加一個異常處理程序,它就不會回滾。所以我更喜歡使用保存點的顯式方法。
如果在異常處理中使用嵌套塊但在主/外部塊中沒有異常處理,它是一個事務嗎? – 2013-12-02 12:43:28
@JonnyLeeds,不,當你開始運行DML語句時,它是一個事務。 – 2013-12-02 22:30:49
你不會提及這是一個匿名PL/SQL塊還是一個聲明式塊,包,程序或功能。 但是,在PL/SQL中必須顯式執行COMMIT以將事務保存到數據庫。 COMMIT實際上將所有未保存的交易從當前用戶的會話保存到數據庫。
如果發生錯誤,事務將隱式執行ROLLBACK。
這是PL/SQL的默認行爲。
我不確定說* transaction是否回滾是正確的;在PL/SQL塊之前所做的任何未提交的更改仍然未決,並且需要由客戶端提交或回滾。在塊中採取的任何操作都將回滾,就好像保存點一樣,我認爲這是您的意思。 (像往常一樣,[湯姆解釋得比我好](http://asktom.oracle.com/pls/asktom/f?p=100:11:0::::P11_QUESTION_ID:43818437682131))。我也不確定OP是否詢問塊內的嵌套塊,以及內部塊中的更改是否將獨立提交/回滾。 – 2012-08-15 14:46:45
BEGIN
- END
塊是PL/SQL的構建塊,每個PL/SQL單元至少包含在一個這樣的塊中。嵌套0- END
PL/SQL塊內的塊通常用於捕獲某些異常並處理該特殊異常,然後引發無關的異常。儘管如此,在PL/SQL中,您(客戶端)必須始終爲事務發出提交或回滾。
如果您希望在包含PL/SQL的事務中執行原子事務,則需要在聲明塊中聲明PRAGMA AUTONOMOUS_TRANSACTION
。這將確保該塊內的任何DML可以獨立於包含事務而被提交或回滾。
但是,您不能爲嵌套塊聲明此附註。您只能聲明此爲:
參考:Oracle
如果這是你正在尋找的行爲,你應該發出顯式的'COMMIT'和'ROLLBACK'語句(可能在'EXCEPTION'部分)。如果您確實需要一個原子事務,請查看Oracle中的AUTONOMOUS_TRANSACTIONS。 – Ollie 2012-08-15 08:27:52