从两个会话中插入唯一列相同的值(Oracle)

时间:2017-05-04 07:23:28

标签: sql oracle transactions insert unique

我有一个问题: 我有一个表T,其中一列具有唯一约束

CREATE TABLE T (ID NUMBER,
                UNIQUE (ID));

第1节已完成对该表的插入

INSERT INTO T(id) VALUES(1);

会话2 正在尝试将相同的值合并到该表

 MERGE INTO t
 USING (SELECT 1 col FROM dual) s
    ON (t.id = s.col)
  WHEN NOT MATCHED THEN 
INSERT (id) VALUES (col);

此时会话2被阻止并等待会话1被提交或回滚。 现在我在第1节

中运行
COMMIT;

此时会话2

发生错误
  

ORA-00001:违反了唯一约束

有什么选择可以避免吗?

P.S。问题是我在同一个表中INSERT到某个表和MERGE(在ON部分使用UNIQUE列)。此INSERT和MERGE在两个不同的会话中单独调用。有时MERGE会因为上面描述的情况而下降。 我希望我把它描述得可以理解

1 个答案:

答案 0 :(得分:1)

您的示例是phantom reads problem的子集。幻影读取,您的问题只是关系数据库的属性。我建议阅读Kleppmann的Designing Data-Intensive Applications第7章。

您的选择不能掉以轻心:

  1. 使用optimistic locks重新设计应用程序。
  2. database isolation level更改为SERIALIZABLE,这会降低单个事务的速度并降低数据库并行运行事务的能力。
  3. 根据我的经验,大多数设计师选择与问题共存的第三种选择。根据您的非功能性要求,最好保持您的应用程序简单而不是在理论上正确。