对象: pickTicket 出库 1 : N pickTicketDetail 出库明细
数据库: pickTicket的id作为pickTicketDetail 的外键(pickTicket.id)
---------
在对pickTicketDetail 某行数据进行insert/update/delete的事务提交给数据库进行持久化处理时,数据库会将
pickTicket整个表给予只读锁. 此为避免修改pickTicketDetail 时,pickTicket的数据进行修改而出现
pickTicketDetail中的pickTicket.id对应在pickTicket中不存在.(即确保数据库的数据完整性)
发生场景: 事件A增删改某表A时,会对该表的所有外键对应的表给予只读锁.如此时其他事务B正提交数据库,类似的需要锁定事件A中已锁定的表.
此时2个事务都在等待对方表解锁.产生死锁.
可以处理方案:
1尽量缩短事务处理的时间.
2对pickTicketDetail 增加pickTicket.id的索引.
------------
相关参考:
发生场景: 事件A增删改某表A时,会对该表的所有外键对应的表给予只读锁.如此时其他事务B正提交数据库,类似的需要锁定事件A中已锁定的表.
此时2个事务都在等待对方表解锁.产生死锁.
可以处理方案:
1尽量缩短事务处理的时间.
2对pickTicketDetail 增加pickTicket.id的索引.
------------
相关参考:
http://it.china-b.com/sjk/oracle/20090826/177376_1.html
测试:
session 1:
SQL> delete from emp where emp.deptno=10;
session 2:
SQL> delete from dept where deptno=40;
现象:在emp的字段deptno没有索引时session 2等待, 有索引则不等待.
结论:如果没有索引时,对父表的操作,会级联加一个TM S锁(level 4)到子表上;
如果有索引时,对父表的操作,会级联加一个TM RS锁(level 2)到子表上;
这时如果子表上本身就有个TM RX锁(这种锁很容易产生,insert update delete都会产生这种锁),
TM S锁和TM RX锁是互斥的, TM RS锁和TM RX锁是相容的.
-------
最后:其实想记录的是"外键未加索引的问题" .此问题可以google下了解.
本文写的较乱,只为存疑记录.有待进一步了解学习.