DB2存儲過程的事務控制以及錯誤處理。

文章主要內容是:如何去控制存儲過程中,出錯了該如何去控制整個事務,以保證數據的完整性,以及和你的預期相吻合。(由於本人用DB2的時間不長,文中有什麼不對的地方,請大家指點迷津。謝謝)

1:先準備一下測試的環境:表TAA和表TBB:

CREATE TABLE TBB
 (ID  INTEGER         NOT NULL  GENERATED BY DEFAULT
    AS IDENTITY (START WITH 1, INCREMENT BY 1, CACHE 20, MINVALUE 1, MAXVALUE 2147483647, NO CYCLE, NO ORDER),
  C1  VARCHAR(128)    NOT NULL
 )
  DATA CAPTURE NONE
  IN USERSPACE1;

ALTER TABLE TBB
  LOCKSIZE ROW
  APPEND OFF
  NOT VOLATILE;

CREATE TABLE TAA
 (ID  INTEGER         NOT NULL  GENERATED BY DEFAULT
    AS IDENTITY (START WITH 1, INCREMENT BY 1, CACHE 20, MINVALUE 1, MAXVALUE 2147483647, NO CYCLE, NO ORDER),
  C1  VARCHAR(128)    NOT NULL
 )
  DATA CAPTURE NONE
  IN USERSPACE1;

ALTER TABLE TAA
  LOCKSIZE ROW
  APPEND OFF
  NOT VOLATILE;

錯誤產生原因:不能把null值插入c1字段。

2:下面來創建測試的存儲過程,一般情況下,沒用過存儲過程的人都會這樣寫:

CREATE PROCEDURE TEST_ZHAOGW ( ) 
  BEGIN
    INSERT INTO TAA (C1) VALUES ('AAAAAAA');
    INSERT INTO TBB (C1) VALUES (null);
end;

其結果是:控制檯提示出錯信息,並且TAA表有一條'AAAAAAA'的記錄。而TBB表是空的。

很多人都認爲存儲過程會自動處理,在存儲過程中,它如果出錯了,會自動幫你回滾存儲過程中所執行的事務。來看下下面一段話:

  SQL procedure body 是存儲過程的主體。其核心是一個複合語句。複合語句由關鍵詞 BEGIN 和 END 包圍。這些語句可以是 ATOMIC 或 NOT ATOMIC 的。默認情況下,它們是 NOT ATOMIC 的。SQL Procedures 要求複合語句中的聲明和可執行語句符合特定的順序。

3:上面的一段話就很好解析爲何剛纔的存儲過程執行的結果了。我們就根據這段話,修改一下存儲過程:

CREATE PROCEDURE TEST_ZHAOGW ( ) 
  BEGIN
P1: BEGIN ATOMIC
    INSERT INTO TAA (C1) VALUES ('AAAAAAA');
    INSERT INTO TBB (C1) VALUES (null);
END P1;
end;

這裏的P1其實可以不要的,如開頭的那行可以是“BEGIN ATOMIC”後面的那行可以是“END;”。如果我沒理解錯,這個P1應該是這個複合語句的名稱吧。 

其結果是:控制檯提示出錯信息,並且TAA和TBB表是空的。(事務是整個複合語句塊回滾了)。

4:下面,大家來看一下,存儲過程中定義錯誤的處理方式:

CREATE PROCEDURE TEST_ZHAOGW ( ) 
  BEGIN
DECLARE   CONTINUE    HANDLER   FOR SQLEXCEPTION
P1: BEGIN ATOMIC
    INSERT INTO TAA (C1) VALUES ('AAAAAAA');
    INSERT INTO TBB (C1) VALUES (null);
    INSERT INTO TAA (C1) VALUES ('bbbbbbbbb');
END P1;
end;

從字面上去理解是:出錯繼續。

其結果是:控制檯提示執行成功。但TAA表和TBB表都沒有插入數據。

5:把BEGIN ATOMIC去掉看看什麼結果(錯誤定義的處理方式):

CREATE PROCEDURE TEST_ZHAOGW ( ) 
  BEGIN
DECLARE   CONTINUE    HANDLER   FOR SQLEXCEPTION

    INSERT INTO TAA (C1) VALUES ('AAAAAAA');
    INSERT INTO TBB (C1) VALUES (null);
    INSERT INTO TAA (C1) VALUES ('bbbbbbbbb');

end;

其結果是:控制檯提示執行成功。但TAA表插入了'AAAAAAA',TBB表插入了'bbbbbbbbb'

我想這個設置,是用在一個存儲過程中,後面的業務與前面的業務沒有任何關聯的,大家的操作都是相互獨立的時候用到的,如設置的定時修復數據的存儲過程。

複合語句:我的理解是:複合語句裏面(begin 和end 之間)的代碼看成是一個sql語句。因此就有了:

CREATE PROCEDURE TEST_ZHAOGW ( ) 
  BEGIN
    INSERT INTO TAA (C1) VALUES ('AAAAAAA');
P1:BEGIN ATOMIC
    INSERT INTO TAA (C1) VALUES ('bbbbbbbbb');
    INSERT INTO TBB (C1) VALUES (null);
end P1;
end;





其結果是:控制檯提示出錯信息,並且TAA表有一條'AAAAAAA'的記錄。而TBB表是空的。它只回滾了複合語句塊裏面的

操作,外面的整個存儲過程的語句塊還是默認的NOT ATOMIC來的。大家還有什麼疑問可以自己繼續測試下,有什麼特殊的發現,可以分享一下。

下面提供一些參考資料,以便大家參考使用:

http://doc.chinaunix.net/db2/200812/207691.shtml

http://weiruan85.javaeye.com/blog/312478

原創作品出自努力偷懶,轉載請說明文章出處http://blog.csdn.net/kfarvid或 http://www.cnblogs.com/kfarvid/

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章