【发布时间】:2019-10-14 11:47:36
【问题描述】:
我有以下与 Spring JDBC 一起使用的方法
public String getState() {
String stateLink = template.queryForObject(
"select state_url from state_scrape_queue where in_use = false ORDER BY scrape_timestamp NULLS FIRST LIMIT 1",
(result, rowNum) -> {
return result.getString("state_url");
});
return stateLink;
}
我找不到如何使用 Spring JDBC 执行 for update 的示例。我希望 in_use 设置为 true 用于更新。
我需要使用 select 进行更新,因为此应用程序将以多线程方式使用。我不希望多个线程获得同一行,防止这种情况的方法是使用select for update
我可以用纯 JDBC 做到这一点,这是我问如何用纯 JDBC 做到这一点的问题
select "for update" with JDBC?
有人知道这是怎么做的吗?
【问题讨论】:
-
FOR UPDATE不会更新任何内容,它只会锁定选定的行,就像它已更新一样。因此,您不能使用FOR UPDATE将某些内容设置为true,您需要执行单独的UPDATE语句。无论如何,使用 spring-jdbc 的工作方式与直接执行语句相同。就目前而言,尚不清楚您真正要问的是什么。 -
更新有它的目的,这就是它存在的原因。它在多线程应用程序中非常有用。它会阻止另一个线程获取同一行,因为使用
select for update会锁定该行,并且在此示例中会将in_use更新为true,因此另一个线程将不会获取同一行。 -
select 中的
for update子句不会更新行,它只会锁定行,因此并发事务无法更新,并且 - 根据锁定模型 - 无法读取该行。您认为它将in_use更改为 true 的假设是错误的。 -
@MarkRotteveel 这个给定的答案是使用纯 JDBC 执行
select for update。 stackoverflow.com/a/46995306/492015我已经用了很长时间了,效果很好。两个线程从来没有得到相同的行。我只需要用 Spring JDBC 做同样的事情 -
使用 JDBCTemplate 也一样。主要区别可能是您的事务边界。链中是否有任何方法调用该方法
@Transactional,如果没有,则表示事务已提交,queryForObject返回时释放的锁。
标签: spring spring-boot jdbc spring-jdbc jdbctemplate