yangtingkun
===========================================================
小议延迟事务的提交
===========================================================

简单记录一下Oracle延迟事务提交的特点。


在测试的时候发现,Oracle延迟事务如果提交时出现了错误,那么Oracle会自动回滚所以的操作。

SQL> CREATE TABLE T (ID NUMBER, NAME VARCHAR2(30));

表已创建。

SQL> CREATE INDEX IND_T_ID ON T(ID);

索引已创建。

SQL> ALTER TABLE T ADD CONSTRAINT PK_T_ID PRIMARY KEY (ID) DEFERRABLE;

表已更改。

首先建立一张表,并建立了可延迟约束的主键信息:

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

已创建 1 行。

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

默认情况下,不能插入违反约束条件的数据。不过通过启用延迟约束,可以使得约束的检查放到事务提交的时刻:

SQL> SET CONSTRAINTS ALL DEFERRED;

约束条件已设置。

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

已创建 1 行。

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

已创建 1 行。

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

已创建 1 行。

SQL> UPDATE T SET ID = ROWNUM;

已更新4行。

SQL> SELECT * FROM T;

ID NAME
---------- ------------------------------
1 A
2 A
3 A
4 A

SQL> COMMIT;

提交完成。

由于启用了延迟约束,使得上面的SQL操作可以成功执行,Oracle只在COMMIT的时刻检查约束是否发生冲突。

不过上面展示的是延迟约束在提交时刻可以满足的情况,对于延迟约束在提交时刻仍然无法满足的情况,会发现Oracle回滚了整个事务。

SQL> SET CONSTRAINTS ALL DEFERRED;

约束条件已设置。

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

已创建 1 行。

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

已创建 1 行。

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

已创建 1 行。

SQL> SELECT * FROM T;

ID NAME
---------- ------------------------------
1 A
2 A
3 A
4 A
5 B
6 C
4 D

已选择7行。

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

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


SQL> SELECT * FROM T;

ID NAME
---------- ------------------------------
1 A
2 A
3 A
4 A

这其实并不难理解,对于COMMIT操作而言,要么执行成功,那么事务被提交,要么出现了错误,事务被回滚。但是用户使用延迟事务时,必须清楚,使用延迟事务并准备提交时,很可能会由于约束冲突而导致本事务所有的修改丢失。

而这种修改的丢失是没有办法避免的,即使设置了SAVEPOINT也没有意义,在延迟事务提交失败后,Oracle会选择回滚到整个事务的开始部分。

yangtingkun 发表于:2008.06.07 23:59 ::分类: ( ORACLE ) ::阅读:(1844次) :: 评论 (0)

发表评论
标题

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

称呼

邮箱地址(可选)

个人主页(可选)

 authimage


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