Oracle - SELECT-INSERT锁定模式

Luk*_*sik 3 oracle concurrency plsql

我有一个表Orders(有列orderId,orderType,userId,state,...).我需要我的流程来执行以下操作:

  1. 检查是否存在具有特定类型的订单,具有特定用户的特定状态(SELECT).
  2. 如果这样的订单不存在 - 创建一个(INSERT).

所以基本上我想确保总是只有一个订单:

  • orderType = x
  • userId = y
  • state = z

然而,我不能创建约束,因为x1,y1,z1可以存在多个订单.

我必须说我在Oracle中没有经验.我已经阅读了关于Oracle中的锁的这篇文章,它认为这里唯一有用的锁类型是:

LOCK TABLE Orders IN EXCLUSIVE MODE
Run Code Online (Sandbox Code Playgroud)

但我认为仅针对某些数据子集锁定整个表格是过度的.我尝试SELECT ... FOR UPDATE OF <update_column>使用不同的列,<update_column>但它们允许我插入新行.

这种类型的并发有什么模式吗?它SELECT ... FOR UPDATE OF ...为Oracle 为SELECT-UPDATE模式创建的接缝.SELECT-INSERT有什么类似的东西吗?

Jus*_*ave 6

您可以创建基于函数的唯一索引来强制执行此类约束.如果要强制执行具有state"完成" 的唯一行,但允许许多行具有state"草稿".

CREATE UNIQUE INDEX idx_index_name
    ON( CASE WHEN state = 'Done' THEN orderType ELSE NULL END,
        CASE WHEN state = 'Done' THEN userId ELSE NULL END,
        CASE WHEN state = 'Done' THEN state ELSE NULL END );
Run Code Online (Sandbox Code Playgroud)