17,377
社区成员
发帖
与我相关
我的任务
分享
create table t_base--创建主表
(id number primary key,
name varchar2(10));
create table t_ref--创建子表
(did number primary key,
dname varchar2(10),
pid number);
alter table T_REF--为子表添加外键
add constraint FK_T_REF foreign key (PID)
references T_BASE (ID);
--窗口1
insert into t_base--执行后不commit,去窗口2执行insert
values(1,'aa');
--窗口2
insert into t_ref--锁等待
values(1,'ba',1);
问题来了,既然oracle是 read committed,窗口2的执行语句看不到窗口一得执行语句,
为什么不返回ORA-02291: 违反完整约束条件 (SCOTT.FK_T_REF) - 未找到父项关键字,
而是被阻塞,这跟 read committed 不矛盾么?
create table t_base--创建主表
(id number primary key,
name varchar2(10));
create table t_ref--创建子表
(did number primary key,
dname varchar2(10),
pid number);
alter table T_REF--为子表添加外键
add constraint FK_T_REF foreign key (PID)
references T_BASE (ID);
--窗口1
insert into t_base--作成成功,未commit
values(1,'aa');
--窗口2
insert into t_base--作成成功,未commit,未等待
values(2,'bb');
--窗口1
insert into t_ref--作成成功,未commit,未等待
values(1,'ba',1);
--窗口2
insert into t_ref--作成成功,未commit,未等待
values(2,'ba',2);
--窗口1
insert into t_base--锁等待
values(2,'bb');
----------------------------
--自己理解:提交读(read committed)事务隔离级别:虽然不会出现脏读,但是会出现幻象和非重复读。
--事务1先于事务2开始,并保持未提交状态,事务2想要修正正被事务1修改的行,那么事务2等待!
--只有事务1提交或回滚,事务2才能进行修改;
--如果事务2修正非事务1修正行,则可以正常修正!
ADDR KADDR SID TYPE ID1 ID2 LMODE REQUEST CTIME BLOCK
5AF4172C 5AF41744 132 TM 70088 0 3 0 59 0
5AF417F0 5AF41808 132 TM 70091 0 2 0 59 0
5AFAE748 5AFAE864 132 TX 524289 7056 6 0 59 1
5AFA6F84 5AFA70A0 140 TX 196608 7050 6 0 12 0
5B434398 5B4343AC 140 TX 524289 7056 0 4 12 0
5AF41668 5AF41680 140 TM 70091 0 3 0 12 0
5AF415A4 5AF415BC 140 TM 70088 0 2 0 12 0
--当我在窗口1中用排它锁
scott@YPCOST> lock table t_base in exclusive mode;
表已锁定。
--窗口2就会出现等待,而不是报ORA-02291 错误
--窗口1进行的操作
scott@YPCOST> create table t_base--创建主表
2 (id number primary key,
3 name varchar2(10));
表已创建。
scott@YPCOST> create table t_ref--创建子表
2 (did number primary key,
3 dname varchar2(10),
4 pid number);
表已创建。
scott@YPCOST>
scott@YPCOST> alter table T_REF--为子表添加外键
2 add constraint FK_T_REF foreign key (PID)
3 references T_BASE (ID);
表已更改。
scott@YPCOST> select * from t_base for update;--行级所 这样其他用户可以进行查询操作
未选定行
--窗口2
scott@YPCOST> insert into t_ref--锁等待
2 values(1,'ba',1);
insert into t_ref--锁等待
*
第 1 行出现错误:
ORA-02291: 违反完整约束条件 (SCOTT.FK_T_REF) - 未找到父项关键字
/*
个人观点:想t_base里insert 是属于排他锁,这个未提交。
你向t_ref里insert时无法去读取t_base里的数据 所以就一直等到
*/