<rt id="bn8ez"></rt>
<label id="bn8ez"></label>

  • <span id="bn8ez"></span>

    <label id="bn8ez"><meter id="bn8ez"></meter></label>

    posts - 56, comments - 54, trackbacks - 0, articles - 4
       ::  ::  :: 聯系 :: 聚合  :: 管理

    PL/SQL支持嵌套事務

    Posted on 2006-01-27 16:20 Terry的Blog 閱讀(2256) 評論(1)  編輯  收藏 所屬分類: oracle

    使用場景:
    當一個PL/SQL程序執行出錯 需要輸出log信息到數據庫表中的時候 就會遇到這個難題.
    log的內容要提交到表中 但是前面出錯的內容卻不能提交.雖然我們可以在出錯時先Rollback 等log好了
    再commit.但是這樣畢竟比較麻煩.實際上PL/SQL本身支持嵌套事務.
    看下面的小例子:
    CREATE OR REPLACE procedure Test1
    as
    PRAGMA AUTONOMOUS_TRANSACTION; -- 關鍵就是這句
    begin
    --set transaction read write;
    insert into aaa values(1,4,7);
    commit;
    end;
    /

    CREATE OR REPLACE procedure Test2
    as
    begin
    --set transaction read write;
    insert into aaa values(2,5,8);
    Test1;
    insert into aaa values(3,6,9);
    rollback;
    end;
    /
    當execute Test2完了時在AAA表中插入了一行(1,4,7)。

    --------------------------------------------------------------------------------------------------------------------------
    理論知識:
    AUTONOMOUS TRANSACTION(自治事務)的介紹:

    在基于低版本的ORACLE做一些項目的過程中,有時會遇到一些頭疼的問題.,比如想在執行當前一個由多個DML組成的transaction(事務)時,為每一步DML記錄一些信息到跟蹤表中,由于事務的原子性,這些跟蹤信息的提交將決定于主事務的commit或rollback. 這樣一來寫程序的難度就增大了, 程序員不得不把這些跟蹤信息記錄到類似數組的結構中,然后在主事務結束后把它們存入跟蹤表.哎,真是麻煩!

    有沒有一個簡單的方法解決類似問題呢?

    ORACLE8i的AUTONOMOUS TRANSACTION(自治事務,以下AT)是一個很好的回答。

    AT 是由主事務(以下MT)調用但是獨立于它的事務。在AT被調用執行時,MT被掛起,在AT內部,一系列的DML可以被執行并且commit或rollback.

    注意由于AT的獨立性,它的commit和rollback并不影響MT的執行效果。在AT執行結束后,主事務獲得控制權,又可以繼續執行了。

    如何實現AT的定義呢?我們來看一下它的語法。其實非常簡單。

    只需下列PL/SQL的聲明部分加上PRAGMA AUTONOMOUS_TRANSACTION 就可以了。

    1.  頂級的匿名PL/SQL塊

    2.  Functions 或 Procedure(獨立聲明或聲明在package中都可)

    3.  SQL Object Type的方法

    4.  觸發器。

      比如:

     在一個獨立的procedure中聲明AT

    CREATE OR REPLACE PROCEDURE

       Log_error(error_msg IN VARCHAR2(100))

    IS

       PRAGMA AUTONOMOUS_TRANSACTION;

    BEGIN

       Insert into Error_log values ( sysdate,error_msg);

       COMMIT;

    END;

    下面我們來看一個例子,(win2000 advanced server + oracle8.1.6 , connect as scott)

    建立一個表:

    create table msg (msg varchar2(120));

    首先,用普通的事務寫個匿名PL/SQL塊:

     declare

       cnt  number := -1;   --} Global variables

       procedure local is

       begin

          select count(*) into cnt from msg;

          dbms_output.put_line('local: # of rows is '||cnt);

          insert into msg values ('New Record');

          commit;

       end;

     

       begin

          delete from msg ;

          commit;

          insert into msg values ('Row 1');

          local;

          select count(*) into cnt from msg;

          dbms_output.put_line('main: # of rows is '||cnt);

          rollback;

          local;

          insert into msg values ('Row 2');

          commit;

          local;

          select count(*) into cnt from msg;

          dbms_output.put_line('main: # of rows is '||cnt);

       end;

    運行結果(注意打開serveroutput)

    local: # of rows is 1   -> 子程序local中可以’看到’主匿名塊中的uncommitted記錄

    main: # of rows is 2    -> 主匿名塊可以’看到’2條記錄(它們都是被local commit掉的)

    local: # of rows is 2   -> 子程序local首先’看到’2條記錄,然后又commit了第三條記錄

    local: # of rows is 4   -> 子程序local又’看到’了新增加的記錄(它們都是被local commit掉的),然后又commit了第五條記錄

    main: # of rows is 5    -> 主匿名塊最后’看到’了所有的記錄.

    從這個例子中,我們看到COMMIT和ROLLBACK的位置無論是在主匿名塊中或者在子程序中,都會影響到整個當前事務.

    現在用AT改寫一下匿名塊中的procedure local:

    ...

       procedure local is

          pragma AUTONOMOUS_TRANSACTION;

       begin

    ...

    重新運行(注意打開serveroutput)

    local: # of rows is 0   -> 子程序local中無法可以’看到’主匿名塊中的uncommitted記錄 (因為它是獨立的)

    main: # of rows is 2    -> 主匿名塊可以’看到’2條記錄,但只有一條是被commited.

    local: # of rows is 1   -> 子程序local中可以’看到’它前一次commit的記錄,但是主匿名塊中的記錄已經被提前rollback了

    local: # of rows is 3   -> 子程序local 中可以’看到’3條記錄包括主匿名塊commit的記錄

    main: # of rows is 4    ->主匿名塊最后’看到’了所有的記錄.

    很明顯,AT是獨立的,在它執行時,MT被暫停了. AT的COMMIT,ROLLBACK并不影響MT的執行.

    運用AT時,有一些注意事項,簡單列舉如下:

    1.     在匿名PL/SQL塊中,只有頂級的匿名PL/SQL塊可以被設為AT

    2.     如果AT試圖訪問被MT控制的資源,可能有deadlock發生.

    3.     Package 不能被聲明為AT,只有package所擁有的function和procedure 才能聲明為AT

    4.     AT程序必須以commit 或rollback結尾,否則會產生Oracle錯誤ORA-06519: active autonomous transaction detected and rolled back

    在程序開發時,如果充分運用AUTONOMOUS TRANSACTION的特性,一定能取得事倍功半的效果.


    評論

    # re: PL/SQL支持嵌套事務  回復  更多評論   

    2013-03-20 00:59 by
    但是
    主站蜘蛛池模板: 日韩高清在线免费看| 99久久国产热无码精品免费 | 日韩电影免费在线观看网址| 毛片A级毛片免费播放| 精品日韩99亚洲的在线发布 | 国产极品粉嫩泬免费观看| 亚洲色精品三区二区一区| 毛片在线免费视频| 亚洲中文字幕乱码AV波多JI| 成年女人毛片免费观看97| 中文字幕精品三区无码亚洲| 日本免费人成黄页网观看视频 | 日韩在线视精品在亚洲| 免费国产成人高清视频网站 | 日本一卡精品视频免费| 亚洲精品国产免费| 国产高清免费视频| 亚洲欧美国产日韩av野草社区| 日本黄页网站免费| 一级免费黄色毛片| 亚洲avav天堂av在线不卡| 国产精品久久永久免费| 亚洲欧美日韩综合俺去了| 国产男女猛烈无遮挡免费视频| 乱淫片免费影院观看| 亚洲va国产va天堂va久久| 91精品啪在线观看国产线免费| 亚洲影视自拍揄拍愉拍| 亚洲?v女人的天堂在线观看| 最近更新免费中文字幕大全| 精品无码一区二区三区亚洲桃色 | 亚洲欧洲日韩国产一区二区三区| 成人黄软件网18免费下载成人黄18免费视频 | 狠狠色香婷婷久久亚洲精品| 卡一卡二卡三在线入口免费| 色吊丝性永久免费看码| 久久久久亚洲精品日久生情| 免费看AV毛片一区二区三区| 中文字幕无码免费久久9一区9| 亚洲综合图片小说区热久久| 国产伦一区二区三区免费|