JDBC批处理更新的所有行的原子锁定

Raf*_*ter 5 oracle jdbc database-concurrency

我有两个线程在与表类似的表上运行并发更新:

CREATE TABLE T (
  SEQ NUMBER(10) PRIMARY KEY,
  VAL1 VARCHAR2(10),
  VAL2 VARCHAR2(10)
)
Run Code Online (Sandbox Code Playgroud)

该表包含大量条目,其中的更新类似于:

UPDATE T SET VAL1 = ? WHERE SEQ < ?
UPDATE T SET VAL2 = ? WHERE SEQ = ?
Run Code Online (Sandbox Code Playgroud)

这两个语句都在两个不同的事务中运行,这都是JDBC批处理更新,每个批处理都有1000行。这样做时,我遇到了ORA-00060:在相当快地等待资源时检测到死锁。我假设这两个事务都会部分影响相同的行,因为这两个事务都设法将某些行锁定在另一行之前。

有没有一种方法可以通过使锁定成为原子来避免这种情况,或者我需要在两个线程之间引入某种形式的显式锁定?

Vla*_*cea 7

当您更新记录时,将采取锁定措施以防止脏写会损害原子性。

但是,您可以使用“ 跳过锁定”。这样,在尝试执行更新之前,您尝试使用“跳过锁定”获取FOR UPDATE锁定。这将使您可以锁定计划修改的记录,也可以跳过已被其他并发事务锁定的记录。

查看SkipLockJobQueueTest我的高性能Java持久性GitHub存储库中的示例,了解如何使用“跳过锁定”。

有关“跳过锁定”的更多详细信息,请参阅本文