Oracle锁定多个插入的索引

时间:2013-11-26 22:29:57

标签: oracle hibernate indexing database-partitioning database-locking

我遇到了这个问题,但尚未找到解决方案:

我有一个包含多个表的应用程序(像大多数应用程序一样)。

其中两个表是:

TB_POLICY
---------
id number(18) : PK
... some other columns

TB_REDEMPTION
-------------
id number(18) : PK
fk_policy number(18) : NOT NULL, FK
... some other columns

TB_POLICY按部分字段的哈希值进行分区,TB_REDEMPTION按照fk_policy关系的引用进行分区。

TB_POLICY包含大约50,000条记录,表TB_REDEMPTION包含大约25,000,000条记录。

有一个用例,其中应用程序在TB_POLICY中插入单个记录,在TB_REDEMPTION中在单个事务中插入大量记录(大约200-300条记录)。

当我在代码中标记断点,在所有插入(在两个表中)之后,以及在提交事务之前,没有办法从另一个数据库连接向TB_REDEMPTION插入另一条记录(甚至直接来自SQL * Plus) - 它只是等待!

我们分析了很多东西,发现PK_REDEMPTION上发生了锁定(TB_REDEMPTION的主键索引)。

如何防止此锁定?我在网上搜索过,在插入过程中没有找到关于索引锁的任何内容。

我要提到的是,这个应用程序是基于Web的,并且有许多并发用户使用相同的用例,并且用户锁定主键索引,阻止其他用户的工作,并且对性能有非常糟糕的影响。应用

另一点,应用程序是由Spring / Hibernate开发的,因此事务管理由Spring完成,而DML语句由Hibernate创建。我们正在使用Oracle 11g。

1 个答案:

答案 0 :(得分:0)

我已经解决了这个问题,TB_REDEMPTION有另一个外键FK_PAY,它是唯一但可以为空的。

定义为:

alter table tb_redemption add constraint uk_rdm_pay unique(fk_pay);

但问题是如果所有索引属性都为null,Oracle不会将索引添加到索引中。因此,当插入fk_pay等于null的记录时,Oracle会锁定表而不是索引中的记录,这是问题的根源。

我通过删除唯一约束并定义以下唯一索引来解决问题:

create unique index ux_rdm_pay on tb_redemption(fk_pay, case when fk_pay is null then id end);

因此唯一索引强制关系的唯一性,并且索引的字段永远不会是null,因此表中的所有记录都将被编入索引并且它会阻止表锁定。