在Oracle SQL更新语句中,假设更新会影响5行,update语句是否会同时或按顺序更新所有5行? E.g。
UPDATE table1
set column2 = 'completed' WHERE
index between 1 AND 5
在上面的陈述中,索引1到5会按顺序更新,即1,2,3,4然后5,或者它会同时发生(1-5同时发生)。
我曾提到Oracle documentation,但似乎没有提到这一点。
答案 0 :(得分:4)
潜在的。
在这种情况下,由于您只是更新了5行,因此并行DML非常不合适。假设UPDATE
不调用并行DML,则行将按顺序更新,但更新行的顺序是任意的。 INDEX
1可能是第一个要更新,最后一个要更新,或者可以在中间更新。这取决于查询计划。
答案 1 :(得分:4)
执行UPDATE语句后,语句的效果将对事务的其余部分可见(如果提交,则对其他事务可见)。 Oracle实际执行的顺序是实现细节(类似地,不保证SELECT结果的顺序除非指定ORDER BY)。
在大多数情况下,此订单对客户来说无关紧要。一种情况可能是避免与另一个更新重叠行集的事务发生死锁。 UPDATE将锁定正在更新的行,直到事务结束,因此如果两个事务尝试锁定相同的行,但顺序不同,则可能会出现死锁。
避免死锁的标准方法是始终锁定明确定义的顺序。不幸的是,UPDATE没有ORDER BY子句,但你可以这样做:
SET TRANSACTION ISOLATION LEVEL SERIALIZABLE;
SELECT ... WHERE condition ORDER BY ... FOR UPDATE;
UPDATE ... WHERE condition;
COMMIT;
两个语句的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;
/
答案 2 :(得分:2)
您提供的链接确实涵盖了这一点。 Oracle总是强制执行语句级读取一致性 - 这意味着对table1的查询不会返回一些更新的记录,而有些则不会。无论隔离级别如何,它都将是全部或全部。
答案 3 :(得分:2)
UPDATE,DELETE和INSERT没有已定义的订单。从概念上讲,它们适用于一组并且一次完成。实际上,不要依赖于你可能观察到的任何序列 - 这是一个可以改变的实现细节,只有因为现实世界妨碍理论才会发生。
答案 4 :(得分:0)
所有记录将在一次交易中更新为一条记录。 Oracle不保证更新顺序中的任何顺序。
您可以通过表中的dbms_transaction.local_transaction_id值更新任何字段以进行检查。