sql - select for update 如何适用于具有多行/结果的查询?

标签 sql postgresql select-for-update

鉴于此交易:

select * from table_a where field_a = 'A' for update;

假设这会给出多行/结果,数据库会立即锁定所有结果吗?或者它会一次锁定一行。

如果后者为真,是否意味着并发运行此查询会导致死锁?

那么需要增加一个order by来保持订单的一致性来解决这个问题吗?

最佳答案

documentation解释发生的事情如下:

FOR UPDATE

FOR UPDATE causes the rows retrieved by the SELECT statement to be locked as though for update. This prevents them from being locked, modified or deleted by other transactions until the current transaction ends. That is, other transactions that attempt UPDATE, DELETE, SELECT FOR UPDATE, SELECT FOR NO KEY UPDATE, SELECT FOR SHARE or SELECT FOR KEY SHARE of these rows will be blocked until the current transaction ends; conversely, SELECT FOR UPDATE will wait for a concurrent transaction that has run any of those commands on the same row, and will then lock and return the updated row (or no row, if the row was deleted). Within a REPEATABLE READ or SERIALIZABLE transaction, however, an error will be thrown if a row to be locked has changed since the transaction started. For further discussion see Section 13.4.

您问题的直接答案是 Postgres 无法“立即”锁定所有行;它必须先找到它们。请记住,这是行级锁定而不是表级锁定。

文档包含此注释:

SELECT FOR UPDATE modifies selected rows to mark them locked, and so will result in disk writes.

我将其解释为 Postgres 执行 SELECT 查询并在找到行时将它们标记为已锁定。当 Postgres 识别该行时,锁定(对于给定的行)开始。它一直持续到交易结束。

基于此,我认为使用SELECT FOR UPDATE可能会出现死锁情况。

关于sql - select for update 如何适用于具有多行/结果的查询?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/36321204/

相关文章:

sql - 合并来自两个不同列的两个对象数组,以在 postgresql 中创建一个新的唯一且非空对象数组

sql - 我们可以在 SQL Server 中对 2 个以上的列执行排序吗

postgresql - Postgres - 相同的查询两个不同的解释计划

ruby-on-rails - 使用 DATE_TRUNC ('week' ),如果一周的 .sum( :points) has 0?

java - 如何使用 JSONB PostgreSQL 通过 JSON 插入列?

multithreading - 选择更新行为

mysql - 使用 SELECT .. FOR UPDATE LIMIT 1 时应锁定多少行

mysql - SQL VIEW 只返回第一条记录

sql - 如何查询GROUP BY一年中的月份

java - 使用 JDBC 选择 "for update"?