关于主外键表数据提交过程中的一点疑惑

[复制链接]
查看11 | 回复9 | 2015-3-4 14:19:44 | 显示全部楼层 |阅读模式
关于主外键表数据提交过程中的一点疑惑

一直有疑问,Oracle是基于事务的,事务内的所有操作必须一次性提交,要么成功要么失败。
建了一张简单的主表和引用表,如果分开插入数据并提交当然是没问题的,问题就在于放在一个事务内去提交的话,假设主表先插数据,但是应该还没有写入到数据库中,然后再引用表中再插入数据,为什么能够一次性提交成功或者失败呢? 还没有写到主表中,当然写引用表的时候会缺乏关联关系啊,不过事实上已经成功了

还有类似的操作
例如
Insert into temptable select 1 from onetable;
Insert into temptable select count(*) from temptable;
事实上已经按照顺序写入了

-- Create table
create table ChildTable
(
ID number(20,0),

Name Varchar2(20)
);
-- Create/Recreate primary, unique and foreign key constraints
alter table ChildTable
add constraint ChildTablePrimarykey primary key (ID);

-- Create table
create table MainTable
(
ID number(20,0),
ForeignID number(20,0),
Name Varchar2(20)
);
-- Create/Recreate primary, unique and foreign key constraints
alter table MainTable
add constraint MainTablePrimarykey primary key (ID);
-- Create/Recreate primary, unique and foreign key constraints
alter table MAINTABLE
add constraint MainTableForeignKEY foreign key (ForeignID)
references ChildTable (ID);

INSERT INTO ChildTable VALUES(1,'ChildA');
COMMIT;
INSERT INTO MainTable VALUES(1,1,'MainA');
COMMIT;

-- Created on 2008-1-9 by bq_wang
BEGIN
-- Test statements here
SAVEPOINT do_insert;
INSERT INTO ChildTable VALUES(2,'ChildA');
INSERT INTO MainTable VALUES(2,2,'MainA');
COMMIT WORK ;
EXCEPTION
WHEN OTHERS THEN
ROLLBACK TO do_insert;

DBMS_OUTPUT.put_line('ERROR');
END;

回复

使用道具 举报

千问 | 2015-3-4 14:19:44 | 显示全部楼层
TX锁
在 parent key 所在的table中插入数据,不提交,使用sys用户看不到数据插入,不过使用这个表所在的用户登入似乎可以看到数据 。
回复

使用道具 举报

千问 | 2015-3-4 14:19:44 | 显示全部楼层
同一个表的东西是不是也是这样
Insert into temptable select 1 from onetable;
Insert into temptable select count(*) from temptable;
回复

使用道具 举报

千问 | 2015-3-4 14:19:44 | 显示全部楼层
我的理解是,
主表lookup子表查找refrence key的时候,肯定是lookup了包括还在缓冲区里面的脏数据。
证明:
SQL>INSERT INTO ChildTable VALUES(3,'ChildA');
1 row created.

这个时候还没有写入数据文件,只是在缓冲区里面。
SQL> INSERT INTO MainTable VALUES(3,3,'MainA');
1 row created.
为什么能找到关系键,应该扫面了缓冲区。
回复

使用道具 举报

千问 | 2015-3-4 14:19:44 | 显示全部楼层
你的这东西和一种情况类似
insert into table values(1);
假设session 1执行了这个语句,那么对于session 1这个会话来说,1是可见的
但是对于别的session来说1是不可见
回复

使用道具 举报

千问 | 2015-3-4 14:19:44 | 显示全部楼层
有没有什么具体的机制和理论介绍啊


回复

使用道具 举报

千问 | 2015-3-4 14:19:44 | 显示全部楼层
我的问题在于这两个表有主外键约束,为什么没写入基础表之前引用表就能写入了


回复

使用道具 举报

千问 | 2015-3-4 14:19:44 | 显示全部楼层
1.一致读,
2.子表(引用的表)的引用字段可以为空
回复

使用道具 举报

千问 | 2015-3-4 14:19:44 | 显示全部楼层
3.还有deffer constraint.
回复

使用道具 举报

千问 | 2015-3-4 14:19:44 | 显示全部楼层
好像你说的也不成立啊,你可以试试看直接插入那张引用表,肯定是通不过的
回复

使用道具 举报

您需要登录后才可以回帖 登录 | 立即注册

本版积分规则

主题

0

回帖

4882万

积分

论坛元老

Rank: 8Rank: 8

积分
48824836
热门排行