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

Tat*_*ana 6 sql oracle transactions insert unique

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

CREATE TABLE T (ID NUMBER,
                UNIQUE (ID));
Run Code Online (Sandbox Code Playgroud)

会话1完成插入该表

INSERT INTO T(id) VALUES(1);
Run Code Online (Sandbox Code Playgroud)

第2节尝试将相同的值合并到该表

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

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

COMMIT;
Run Code Online (Sandbox Code Playgroud)

此时会话2中发生错误

ORA-00001:违反了唯一约束

有什么选择我怎么能避免它?

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

Ste*_*len 1

您的示例是幻读问题的一个子集。幻读和您的问题只是关系数据库的一个属性。我建议阅读 Kleppmann 的《设计数据密集型应用程序》的第 7 章。

您的选择不应掉以轻心:

  1. 使用乐观锁重新设计应用程序。
  2. 将数据库隔离级别更改为 SERIALIZABLE,这会减慢单个事务的速度并降低数据库并行运行事务的能力。

根据我的经验,大多数设计师都会选择第三种选择,接受这个问题。根据您的非功能需求,保持应用程序简单比理论上正确可能更好。