下面通过简单的例子说明存储过程、触发器与事务之间的关系:
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/,如需转载,请注明出处,否则将追究法律责任。
转载于:http://blog.itpub.net/23135684/viewspace-709920/