在Oracle SQL更新语句中,行更新是否同时发生?

Ted*_*Ted 7 database oracle concurrency sql-update

在Oracle SQL更新语句中,假设更新会影响5行,update语句是否会同时或按顺序更新所有5行?例如

UPDATE table1 
set column2 = 'completed' WHERE
index between 1 AND 5
Run Code Online (Sandbox Code Playgroud)

在上面的陈述中,索引1到5将按顺序更新,即1,2,3,4然后5,或者它会同时发生(1-5同时发生).

我曾参考过Oracle文档,但似乎没有提到这一点.

Bra*_*vic 4

执行 UPDATE 语句后,该语句的效果将对事务的其余部分可见(如果您提交,则对其他事务可见)。Oracle 实际执行的顺序是一个实现细节(类似地,除非指定 ORDER BY ,否则无法保证 SELECT 结果的顺序)。


在大多数情况下,这个顺序对客户来说并不重要。一种可能的情况是避免与正在更新重叠行集的另一个事务发生死锁。UPDATE 将锁定正在更新的行,直到事务结束,因此如果两个事务尝试锁定相同的行,但顺序不同,则可能会发生死锁。

避免死锁的标准方法是始终以明确定义的顺序进行锁定。不幸的是,UPDATE 没有 ORDER BY 子句,但您可以这样做:

SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT ... WHERE condition ORDER BY ...  FOR UPDATE;
UPDATE ... WHERE condition;
COMMIT;
Run Code Online (Sandbox Code Playgroud)

condition两个语句的位置相同。WHERE为了始终在两个语句中看到相同的行集,可序列化隔离级别是必需的。

或者,在 PL/SQL 中你可以这样做:

DECLARE
    CURSOR CUR IS SELECT * FROM YOUR_TABLE WHERE condition ORDER BY ... FOR UPDATE;
BEGIN
    FOR LOCKED_ROW IN CUR LOOP
        UPDATE YOUR_TABLE SET ... WHERE CURRENT OF CUR;
    END LOOP;
END;
/
Run Code Online (Sandbox Code Playgroud)