通过大量的实验,我发现
(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"
);
我有两个问题
从文档中引用 读取稳定性(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支持部门询问并得到相应的说明),这样的行为在未来可能不会改变。