儲存過程、觸發器與事務之間的關係

尛樣兒發表於2011-10-30


       下面透過簡單的例子說明儲存過程、觸發器與事務之間的關係:

SQL> create table a(id number);

表已建立。

SQL> create table b(id number);

表已建立。

SQL> create or replace trigger test_a1
  2    before insert on a
  3    for each row
  4  declare
  5  begin
  6    insert into b values(:new.id);
  7  end test_a1;
  8  /

觸發器已建立

SQL> insert into a values(1);

已建立 1 行。

SQL> select * from a;

        ID
----------
         1

SQL> select * from b;

        ID
----------
         1

SQL> rollback;

回退已完成。

SQL> select * from a;

未選定行

SQL> select * from b;

未選定行

SQL> create unique index idx_b1 on b(id);

索引已建立。

SQL> insert into b values(2);

已建立 1 行。

SQL> commit;

提交完成。

SQL> insert into a values(2);
insert into a values(2)
            *
第 1 行出現錯誤:
ORA-00001: 違反唯一約束條件 (XIAOYANG.IDX_B1)
ORA-06512: 在 "XIAOYANG.TEST_A1", line 3
ORA-04088: 觸發器 'XIAOYANG.TEST_A1' 執行過程中出錯

SQL> select * from a;

未選定行

        從上面的例子可以看出,向A表中插入資料和觸發器TEST_A1向B表插入資料是在同一個事務中,要麼都成功,要麼都失敗,如果由於某種原因導致觸發器向B表插入資料失敗,那麼整個事務失敗,向A表插入資料也就失敗。

        從另一個角度來說,在觸發器中不允許有COMMIT語句的出現,例如:
SQL> create or replace trigger XIAOYANG.test_a1
  2    before insert on a
  3    for each row
  4  declare
  5  begin
  6    insert into b values(:new.id);
  7    commit;
  8  end test_a1;
  9  /

觸發器已建立

SQL>
SQL> insert into a values (3);
insert into a values (3)
            *
第 1 行出現錯誤:
ORA-04092: COMMIT 不能在觸發器中
ORA-06512: 在 "XIAOYANG.TEST_A1", line 4
ORA-04088: 觸發器 'XIAOYANG.TEST_A1' 執行過程中出錯

        這個設計也是為了確保觸發器操作和SQL語句的操作在同一個事務而設計的限制條件吧!
        然而儲存過程中允許有COMMIT的出現,也就是說,呼叫儲存過程的SQL語句和儲存過程中的SQL語句可能在不同的事務中。

        由此可以大概得出出現結論:觸發器能夠確保與觸發的SQL在同一個事務中,那麼在執行主表的DML語句的時候,由於觸發器的存在可能導致主表DML語句效能的下降。而儲存過程不能確保與呼叫SQL在同一個事務中。

觸發器的觸發級別請參考文章:http://space.itpub.net/23135684/viewspace-712450

來自 “ ITPUB部落格 ” ,連結:http://blog.itpub.net/23135684/viewspace-709920/,如需轉載,請註明出處,否則將追究法律責任。

相關文章