如何进行安全的“选择更新”在 DB2 上的多个表上使用 WHERE 条件?
问题
在 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
查询?
Problem
On a DB2 (version 9.5) the SQL statement
SELECT o.Id FROM Table1 o, Table2 x WHERE [...] FOR UPDATE WITH RR
gives me the error message SQLSTATE=42829
(The FOR UPDATE clause is not allowed because the table specified by the cursor cannot be modified).
Additional info
I need to specify WITH RR
, because I'm running on isolation level READ_COMMITTED
, but I need my query to block while there is another process running the same query.
Solution so far...
If I instead query like this:
SELECT t.Id FROM Table t WHERE t.Id IN (
SELECT o.Id FROM Table1 o, Table2 x WHERE [...]
) FOR UPDATE WITH RR
everything works fine.
New problem
But now I occasionally get deadlock exceptions when multiple processes perform this query simultaneously.
Question
Is there a way to formulate the FOR UPDATE
query without introducing a place where a deadlock can occur?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
首先,对于隔离级别
READ_COMMITTED
,您不需要指定WITH RR
,因为这会导致隔离级别SERIALIZABLE
。指定WITH RS
(读取稳定性)就足够了。要将
FOR UPDATE WITH RS
传播到内部选择,您必须另外指定USE AND KEEP UPDATE LOCKS
。因此,完整的语句如下所示:
我通过 JDBC 在 DB2 上进行了一些测试,它的工作没有死锁。
First, for having isolation level
READ_COMMITTED
you do not need to specifyWITH RR
, because this results in the isolation levelSERIALIZABLE
. To specifyWITH RS
(Read Stability) is enough.To propagate the
FOR UPDATE WITH RS
to the inner select you have to specify additionallyUSE AND KEEP UPDATE LOCKS
.So the complete statement looks like this:
I made some tests on a DB2 via JDBC and it worked without deadlocks.