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

描述事务与SET CONSTRAINTS语句的关系。

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

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


上面一篇讨论了延迟事务对DDL隐式提交的影响,这里简单讨论一下事务与设置延迟约束的关系。

首先设置延迟约束的语句不必是事务中的第一条语句:

SQL> SELECT * FROM T;

未选定行

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

已创建 1 行。

SQL> SET CONSTRAINTS ALL DEFERRED;

约束条件已设置。

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

已创建 1 行。

这个例子中,在事务开始后执行了SELECTINSERT,然后启用了延迟约束。

第二,延迟约束在事务提交或回滚后自动恢复到非延迟状态:

SQL> UPDATE T SET ID = ROWNUM;

已更新2行。

SQL> COMMIT;

提交完成。

SQL> INSERT INTO T VALUES (1, 'C');
INSERT INTO T VALUES (1, 'C')
*
1 行出现错误:
ORA-00001:
违反唯一约束条件 (YANGTK.PK_T_ID)


SQL> SET CONSTRAINTS ALL DEFERRED;

约束条件已设置。

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

已创建 1 行。

SQL> ROLLBACK;

回退已完成。

SQL> INSERT INTO T VALUES (1, 'C');
INSERT INTO T VALUES (1, 'C')
*
1 行出现错误:
ORA-00001:
违反唯一约束条件 (YANGTK.PK_T_ID)

第三,回滚到一个保存点并不能使得延迟约束回滚到当时的状态:

SQL> SELECT * FROM T;

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

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

已创建 1 行。

SQL> SET CONSTRAINTS ALL DEFERRED;

约束条件已设置。

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

已创建 1 行。

SQL> SAVEPOINT A;

保存点已创建。

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

已创建 1 行。

SQL> UPDATE T SET ID = ROWNUM;

已更新5行。

SQL> SET CONSTRAINTS ALL IMMEDIATE;

约束条件已设置。

SQL> INSERT INTO T VALUES (6, 'F');

已创建 1 行。

SQL> ROLLBACK TO A;

回退已完成。

SQL> SELECT * FROM T;

ID NAME
---------- ------------------------------
1 A
2 B
3 C
1 D

SQL> INSERT INTO T VALUES (1, 'E');
INSERT INTO T VALUES (1, 'E')
*
1 行出现错误:
ORA-00001:
违反唯一约束条件 (YANGTK.PK_T_ID)


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

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

可以看到,虽然回滚到保存点A,但是在保存点A是的延迟约束状态已经不存在了,因此,再插入相同的ID就会导致错误。不过虽然这时不是延迟约束状态,但是已经插入的重复ID并不会报错,只有在提交的时候才会报错。

从上面的几个例子可以看出,延迟约束只是一种状态,可以随时通过SET CONSTRAINTS语句进行设置。而延迟约束状态在事务提交、回滚或发出SET CONSTRAINTS ALL IMMEDIATE语句时结束。

在看最后一个例子:

SQL> SELECT * FROM T;

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

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

已创建 1 行。

SQL> SET CONSTRAINTS ALL DEFERRED;

约束条件已设置。

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

已创建 1 行。

SQL> SAVEPOINT A;

保存点已创建。

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

已创建 1 行。

SQL> ROLLBACK TO A;

回退已完成。

SQL> SELECT * FROM T;

ID NAME
---------- ------------------------------
1 A
2 B
3 C
1 E

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

已创建 1 行。

ROLLBACK TO SAVEPOINT并不会改变延迟约束的状态。而COMMITROLLBACK之所以改变了延迟约束的状态,实际上是COMMITROLLBACK语句使得延迟约束的状态恢复到了默认情况,也就是非延迟状态。

yangtingkun 发表于:2008.06.09 23:46 ::分类: ( ORACLE ) ::阅读:(373次) :: 评论 (3)
re: 小议延迟事务的提交(三) [回复]

LZ能否写一个必须延迟事物才能解决,或者说延迟事物是最佳解决方案的例子?

另外延迟事物如果再考虑并发怎么办?有点怕怕!

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

我觉得第二点:
第二,延迟约束在事务提交或回滚后自动恢复到非延迟状态:
要加个条件,就是当建表时是DEFERRABLE INITIALLY IMMEDIATE时才成立.如果在建表时指定是DEFERRABLE INITIALLY DEFERRED,那是否延迟约束是和是否有事务无关的.

scott@PROD> CREATE TABLE T (ID NUMBER, NAME VARCHAR2(30));

Table created.

scott@PROD> create index ind_t_id on t(id);

Index created.

scott@PROD> alter table t add constraint pk_t_id primary key(id) deferrable initially deferred;

Table altered.

scott@PROD> SELECT deferrable,deferred FROM user_constraints WHERE constraint_name = 'PK_T_ID';

DEFERRABLE DEFERRED
-------------- ---------
DEFERRABLE DEFERRED

scott@PROD> INSERT INTO T VALUES (1, 'a');

1 row created.

scott@PROD> INSERT INTO T VALUES (1, 'b');

1 row created.

scott@PROD> rollback;

Rollback complete.

scott@PROD> INSERT INTO T VALUES (1, 'a');

1 row created.

scott@PROD> INSERT INTO T VALUES (1, 'b');

1 row created.

scott@PROD> commit;
commit
*
ERROR at line 1:
ORA-02091: transaction rolled back
ORA-00001: unique constraint (SCOTT.PK_T_ID) violated

bluegroup 评论于: 2008.09.18 11:40
re: 小议延迟事务的提交(三) [回复]

嗯,确实如bluegroup所说,这里写的特性应该是INITIALLY IMMEDIATE的特性,对于INITIALLY DEFERRED则没有影响。

yangtingkun 评论于: 2008.09.23 14:22

发表评论
标题

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

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


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