11

问题

在 DB2(9.5 版)上,SQL 语句

SELECT o.Id FROM Table1 o, Table2 x WHERE [...] FOR UPDATE WITH RR

给我错误消息SQLSTATE=42829(不允许使用 FOR UPDATE 子句,因为无法修改游标指定的表)。

附加信息

我需要指定WITH RR,因为我在隔离级别上运行READ_COMMITTED,但是当有另一个进程运行相同的查询时,我需要阻止我的查询。

到目前为止的解决方案...

如果我改为这样查询:

SELECT t.Id FROM Table t WHERE t.Id IN (
    SELECT o.Id FROM Table1 o, Table2 x WHERE [...]
) FOR UPDATE WITH RR

一切正常。

新问题

但是现在当多个进程同时执行此查询时,我偶尔会遇到死锁异常。

问题

有没有办法在FOR UPDATE不引入可能发生死锁的地方的情况下制定查询?

4

1 回答 1

15

首先,对于具有隔离级别READ_COMMITTED,您不需要指定WITH RR,因为这会导致隔离级别SERIALIZABLE。指定WITH RS(读取稳定性)就足够了。

要将 传播FOR UPDATE WITH RS到内部选择,您必须另外指定USE AND KEEP UPDATE LOCKS

所以完整的语句如下所示:

SELECT t.Id FROM Table t WHERE t.Id IN (
    SELECT o.Id FROM Table1 o, Table2 x WHERE [...]
) FOR UPDATE WITH RS USE AND KEEP UPDATE LOCKS

我通过 JDBC 在 DB2 上做了一些测试,它没有死锁。

于 2010-10-12T15:39:02.427 回答