日期:2014-05-17  浏览次数:20786 次

插入数据时为什么会造成锁?
表A,表B,表C

表B是表A子表,表C是表B子表,就是说B有外键指向A的主键,C有外键指向B的主键。

现在我对表B进行insert操作,并且事务不提交。

这个时候通过观察V$LOCKED_OBJECT视图,可以发现在表A和表C上形成了ROW-X(SX)的行锁。

我就不明白这锁造成的原因是什么?
表B新增记录,为什么会影响到它的父表和子表呢?

------最佳解决方案--------------------
当表B做insert时,它会锁定A表的父记录,以避免该记录被删除或主键被UPDATE。
与此同时,也会阻塞其他会话对C表的与B表新插入主键关联的insert操作以保证一致性
------其他解决方案--------------------
关键在与你的外键。
------其他解决方案--------------------
引用:
关键在与你的外键。


对头。
------其他解决方案--------------------
引用:
表A,表B,表C

表B是表A子表,表C是表B子表,就是说B有外键指向A的主键,C有外键指向B的主键。

现在我对表B进行insert操作,并且事务不提交。

这个时候通过观察V$LOCKED_OBJECT视图,可以发现在表A和表C上形成了ROW-X(SX)的行锁。

我就不明白这锁造成的原因是什么?
表B新增记录,为什么会影响到它的父表和子表呢?



1)我就不明白这锁造成的原因是什么?
锁造成的原因是你开启了DML事物(insert),从v$lock上应该可以看到2个锁:TX锁、TM锁(主要是RX锁),还有一个是行级锁,不过oracle不用锁列表来维护它,因此,你看不到,要想看到他,必须到block头上的lock锁标志,看是否被改为1了;

2)表B新增记录,为什么会影响到它的父表和子表呢?

--oracle的外键约束造成的。如果你想表B新增记录,而不影响到它的父表和子表,可以先把外键disable掉
------其他解决方案--------------------
引用:
当表B做insert时,它会锁定A表的父记录,以避免该记录被删除或主键被UPDATE。
与此同时,也会阻塞其他会话对C表的与B表新插入主键关联的insert操作以保证一致性



继续请教一下,A表有锁我可以理解了。
但是B表的主键是sequence,向B表插记录时,C表中还没有任何记录与B表新插的记录关联,为什么要锁C表呢?


------其他解决方案--------------------
引用:
引用:
当表B做insert时,它会锁定A表的父记录,以避免该记录被删除或主键被UPDATE。
与此同时,也会阻塞其他会话对C表的与B表新插入主键关联的insert操作以保证一致性


继续请教一下,A表有锁我可以理解了。
但是B表的主键是sequence,向B表插记录时,C表中还没有任何记录与B表新插的记录关联,为什么要锁C表呢?

你需要把外键和数据区分开来,他们是不同对象,存储方式也不一样。
你插不插数据,外键就在哪?不移不动
------其他解决方案--------------------
引用:
引用:
引用:
当表B做insert时,它会锁定A表的父记录,以避免该记录被删除或主键被UPDATE。
与此同时,也会阻塞其他会话对C表的与B表新插入主键关联的insert操作以保证一致性


继续请教一下,A表有锁我可以理解了。
但是B表的主键是sequence,向B表插记录时,C表中还没有任何记录与B表新插的记录关联,……


"你插不插数据,外键就在哪?不移不动 "