简体   繁体   English

'forUpdate().fetchAny(condition)' 会只锁定一行还是多行?

[英]Will 'forUpdate().fetchAny(condition)' lock only one row or multiple rows?

Recently i have switched to Java stack on new position and i got some troubles with Jooq which is used to access db最近我在新的 position 上切换到 Java 堆栈,我在用于访问数据库的 Jooq 上遇到了一些麻烦

My question is: will ForUpdate in the code below block only one row that satisfies another_condition and will be selected or multiple rows that satisfy some_condition我的问题是:下面代码中的 ForUpdate 是否只会阻止满足another_condition的一行并将被选中或满足some_condition的多行

dslContext().select()
.from(my_table)
.where(some_condition)
.forUpdate()
.skipLocked()
.fetchAny(another_condition)

Client side ResultSet reading客户端ResultSet读取

The ResultQuery.fetchAny() method only defines client side behaviour between jOOQ and JDBC. It proceeds to fetch at most one record from the underlying JDBC ResultSet . ResultQuery.fetchAny()方法仅定义 jOOQ 和 JDBC 之间的客户端行为。它继续从底层 JDBC ResultSet中获取最多一条记录。 In short:简而言之:

  • ResultQuery.fetchAny() fetches the first record (if available) from the ResultSet ResultQuery.fetchAny()ResultSet中获取第一条记录(如果可用)
  • ResultQuery.fetchOne() fetches the first record (if available) from the ResultSet and attempts to fetch another one, in case of which it throws TooManyRowsException ResultQuery.fetchOne()ResultSet获取第一条记录(如果可用)并尝试获取另一条记录,如果它抛出TooManyRowsException
  • ResultQuery.fetchSingle() fetches the first record from the ResultSet , throws NoDataFoundException if no such record was found, and attempts to fetch another one, in case of which it throws TooManyRowsException ResultQuery.fetchSingle()ResultSet获取第一条记录,如果没有找到这样的记录则抛出NoDataFoundException ,并尝试获取另一条记录,如果它抛出TooManyRowsException

These methods do not communicate to the server anything about the intended result set usage, so the server doesn't know what you're planning to do.这些方法不会向服务器传达任何有关预期结果集使用的信息,因此服务器不知道您打算做什么。

Server side locking服务器端锁定

This is unrelated to how you use SQL pessimistic locking clauses, such as FOR UPDATE SKIP LOCKED , which is an operation that happens purely on the server side, and ideally on the entire data set satisfying your WHERE , LIMIT , and other clauses.这与您如何使用 SQL 悲观锁定子句无关,例如FOR UPDATE SKIP LOCKED ,这是一个纯粹发生在服务器端的操作,理想情况下是在满足您的WHERELIMIT和其他子句的整个数据集上发生。 Even if this weren't the case, it's always better to be very explicit about everything you know about your SQL query directly in SQL .即使情况并非如此,最好直接在 SQL中非常明确地说明您所知道的有关 SQL 查询的所有信息。

So, since you're going to fetch only one record, why not tell the server, using LIMIT 1 ?因此,既然您打算只获取一条记录,为什么不使用LIMIT 1告诉服务器呢?

dslContext()
    .select()
    .from(my_table)
    .where(some_condition)
    .limit(1)
    .forUpdate()
    .skipLocked()
    .fetchOne();

API side note API 旁注

Note, there's no such thing as being able to pass "another_condition" to fetchAny() .请注意,没有能够将“another_condition”传递给fetchAny()这样的事情。 You probably meant to stream the result and the use Stream.filter() on it, or something like that?您可能是想 stream 结果并在其上使用Stream.filter()或类似的东西? But why would you lock N records and discard most of them?但是为什么要锁定 N 条记录并丢弃其中的大部分呢?

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM