MERGE
当每个会话对主键列使用不同的值(在下面的片段中显示为 *** )时执行并发时id
,如果我在 2 个终端会话中手动执行,一切都很好。
MERGE
INTO x
USING (SELECT *** as id FROM DUAL) MERGE_SRC
ON (x.id = MERGE_SRC.id)
WHEN MATCHED THEN UPDATE SET val = val + 1 WHERE id = ***
WHEN NOT MATCHED THEN INSERT VALUES (***, 99);
COMMIT;
但是,使用 3 个或更多线程运行多线程负载测试时,我会相对较快地遇到ORA-08177 with locked table
. 这是为什么?(为什么它是不确定的,因为它并不总是在事务重叠时发生?)
该表是使用创建的
create table x (id int primary key, val int);
SQL Server btw 从不使用等效的 MERGE 语句引发异常,运行相同的实验。当同时处理同一行时,情况也是如此。
是不是因为 MERGE 可能不是原子的,并且可序列化模式乐观地运行,所以比赛可能只显示有足够的争用?尽管如此,为什么即使不在同一行同时工作也会发生这种情况?
顺便说一句,我尝试使用可用的最严格的锁来解决这个问题是不成功的。因此,非常感谢有关如何使这个原子化的任何想法。看起来放松隔离级别会让我摆脱异常,但是如果在同一行上出现 2 个更新(否则为什么它首先会在可序列化模式下停止),可能会出现不一致的风险。