yangtingkun
===========================================================
小议延迟事务的提交(二)
===========================================================

描述延迟约束语句与DDL隐式提交。

小议延迟事务的提交(一):http://yangtingkun.itpub.net/post/468/463933


上一篇讨论了延迟约束提交的影响,这里再简单讨论一下延迟约束的一些其他特点:

SQL> TRUNCATE TABLE T;

表被截断。

SQL> INSERT INTO T VALUES (1, 'A');

已创建 1 行。

SQL> INSERT INTO T VALUES (2, 'B');

已创建 1 行。

SQL> COMMIT;

提交完成。

SQL> SET CONSTRAINTS ALL DEFERRED;

约束条件已设置。

SQL> INSERT INTO T VALUES (1, 'C');

已创建 1 行。

SQL> TRUNCATE TABLE T;
TRUNCATE TABLE T
*
1 行出现错误:
ORA-02091:
事务处理已回退

ORA-00001:
违反唯一约束条件 (YANGTK.PK_T_ID)


SQL> SELECT * FROM T;

ID NAME
---------- ------------------------------
1 A
2 B

由于延迟约束的特点,COMMIT操作不再是一个肯定成功的操作,如果事务在提交时违反了约束,那么COMMIT就会报错。这就可能引发一个问题,带有隐式提交特性的DDL语句可能因为延迟约束的存在而失败,如上面的例子所示。失败发生在DDL语句之前的COMMIT处,因此例子中的TRUNCATE语句根本没有被执行。

SQL> CREATE TABLE T_LOG (LOGS VARCHAR2(30));

表已创建。

SQL> CREATE OR REPLACE TRIGGER TRI_BEFORE_TRUNCATE BEFORE TRUNCATE ON DATABASE
2 DECLARE
3 PRAGMA AUTONOMOUS_TRANSACTION;
4 BEGIN
5 INSERT INTO T_LOG VALUES ('BEFORE TRUNCATE');
6 COMMIT;
7 END;
8 /

触发器已创建

SQL> SELECT * FROM T;

ID NAME
---------- ------------------------------
1 A
2 B

SQL> SET CONSTRAINTS ALL DEFERRED;

约束条件已设置。

SQL> INSERT INTO T VALUES (1, 'C');

已创建 1 行。

SQL> TRUNCATE TABLE T;
TRUNCATE TABLE T
*
1 行出现错误:
ORA-02091:
事务处理已回退

ORA-00001:
违反唯一约束条件 (YANGTK.PK_T_ID)


SQL> SELECT * FROM T_LOG;

未选定行

可以看到,这种DDL的错误连系统触发器都无法捕获,因为实际上DDL还没有执行,所以,采用延迟事务可能会给DDL执行失败的诊断造成一定的困难。

其实解决这个问题的方法就是在提交或执行DDL之前通过SET CONSTRAINTS ALL IMMEDIATE语句进行约束检查:

SQL> SET CONSTRAINTS ALL DEFERRED;

约束条件已设置。

SQL> INSERT INTO T VALUES (1, 'C');

已创建 1 行。

SQL> SET CONSTRAINTS ALL IMMEDIATE;
SET CONSTRAINTS ALL IMMEDIATE
*
1 行出现错误:
ORA-00001:
违反唯一约束条件 (YANGTK.PK_T_ID)


SQL> UPDATE T SET ID = 3 WHERE NAME = 'C';

已更新 1 行。

SQL> SET CONSTRAINTS ALL IMMEDIATE;

约束条件已设置。

SQL> TRUNCATE TABLE T;

表被截断。

SQL> SELECT * FROM T_LOG;

LOGS
------------------------------
BEFORE TRUNCATE

yangtingkun 发表于:2008.06.08 23:47 ::分类: ( ORACLE ) ::阅读:(443次) :: 评论 (2)
re: 小议延迟事务的提交(二) [回复]

假定:在我印象中,DDL语句是类似下面的结构,我不是很确定,呵呵
commit;
ddl statements...
commit;

猜测:第一个commit的时候,数据库就已经检查数据完整性了。

是否可以解释影响隐式提交语句和这个触发器呢?

kylin 评论于: 2008.06.10 09:24
re: 小议延迟事务的提交(二) [回复]

DDL的流程就是如此。
由于第一个COMMIT失败,所以DDL本身并没有执行,因此触发器也没有触发。

由于DDL的流程在我的印象中是最基本概念,所以文章中并没有详细描述

yangtingkun 评论于: 2008.06.10 10:34

发表评论
标题

在此添加评论
表情符号: smile laughing tongue angry crying sad wassat wink

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


切换风格
新闻聚合
博客日历
文章归档...
最新发表...
最新评论...
最多阅读文章...
最多评论文章...
博客统计...
Blog信息
网站链接...