如何在DB2中使用select进行更新而不转移数据的情况下获得锁?

问题描述 投票:0回答:1

通过大量的实验,我发现

(jdbcTemplate 是一个 JdbcTemplate 并且只是用来方便执行查询。它与问题没有实际关系)

jdbcTemplate.query(
    "select 0 from example where id = 23 for update with rs use and keep update locks", 
    rs -> {
        rs.next();
        return null;
});

获得了对所选行的锁定,而这个没有。

jdbcTemplate.query(
    "select 0 from example where id = 23 for update with rs use and keep update locks", 
    rs -> {
        return null;
});

我假设同样的原因 下面的程序也没有获得锁。

jdbcTemplate.execute(
    "select id from example where id = 23 for update with rs use and keep update locks"
);

我有两个问题

  1. 这到底是怎么回事?
  2. 如何在数据库中执行select for update,使其确实产生锁,但不返回每条选定行的数据?也许是某种脚本?

有一个Github仓库在测试这些(以及更多的变体)。.

java jdbc db2 locking
1个回答
1
投票

从文档中引用 读取稳定性(RS) 隔离级别。

读取稳定性隔离级别只锁定那些应用程序的行。检索 在一个单位的工作中。

-- Rows are locked / accessed during "fetch"
select * from example where id = 23 with rs use and keep update locks;

-- Rows must be accessed either during "execute" / "open" or "fetch" to get the corresponding result
select count(1) from example where id = 23 with rs use and keep update locks;

主要要求做到 RS 是换句话说:如果某个行参与了这个语句的第1-st次调用的结果,那么它一定会以相同的值参与以后每次调用同一语句的结果。

当你只是选择行的时候,它们在 fetch 只。在你获取它们之前,它们不会被访问。没有必要事先锁定这些行来实现上述的逻辑目标。如果可以 "懒 "取锁定需要的行,为什么要降低系统的并发性呢?

但是当你对需要的行进行一些聚合时,它们必须要在 execute open 或在第1阶段 fetch (也是唯一 fetch,因为它是聚合)来锁定相应的行。我相信,这样的行为并没有被记录下来--这只是目前观察到的行为。

我建议你做1 fetch 为了安全起见,还是在聚合语句上加上了""。没有人能够保证(除非你就此向IBM支持部门询问并得到相应的说明),这样的行为在未来可能不会改变。

© www.soinside.com 2019 - 2024. All rights reserved.