Oracle表并行插入时死锁问题排查及提交次数优化咨询
Oracle并行插入死锁原因及提交次数的影响分析
可能的死锁原因
未提交更新的行锁关联冲突
插入本身不会锁定已有行,但如果并行插入触发了隐式操作(比如外键校验、触发器逻辑),这些操作需要访问之前更新未提交的行,就可能形成循环等待。比如更新父表某行未提交,插入子表时外键校验要读取父表该行;同时另一个会话更新父表另一行未提交,插入子表时也要读取对方持有的父表行锁,双向等待就会触发死锁。索引维护的锁竞争
并行插入会同时维护表上的索引(唯一索引、普通索引都算),如果多个插入会话要修改同一索引块(比如插入的记录索引键落在同一个索引块),锁的获取顺序相反就会引发死锁。尤其是之前的更新操作已经修改过该索引块,插入操作的锁请求更容易形成循环等待。表级锁或残留锁冲突
之前的更新操作可能隐性持有了表级锁,或者有未完成的DDL操作残留锁资源。并行插入的会话请求这些锁时,多个会话之间形成循环等待,比如一个会话持有表共享锁等待插入所需的排他锁,另一个会话持有部分资源反向等待,最终触发死锁。触发器/存储过程的额外锁竞争
如果插入操作调用了触发器或存储过程,里面包含额外的数据库操作(比如更新关联表、带for update的查询),这些操作可能和之前的更新或其他插入会话的操作形成锁的循环等待。比如两个插入会话的触发器分别更新同一张表的不同行,但锁的获取顺序完全相反,就会造成死锁。
增加插入提交次数的作用
增加提交次数有一定缓解作用,但无法根治所有情况:
- 提交会立即释放当前会话持有的行锁、索引锁等资源,缩短锁的持有时间,降低多个会话之间形成循环等待的概率。
- 但如果死锁根源是索引块的高频竞争、触发器逻辑缺陷这类问题,仅靠增加提交次数无法彻底解决,还需要配合其他优化手段(比如按分区拆分插入数据、优化索引结构、调整触发器逻辑)。
- 注意频繁提交会增加事务开销,可能拉低插入性能,需要在死锁概率和插入效率之间做平衡。
内容的提问来源于stack exchange,提问作者Sai Prasanth
相关产品推荐
相关产品推荐

