0

我需要锁定多行,但只获取一行作为返回结果,例如锁定用户:2,4 和 7,但只获取用户的数据where id = 2

好吧,据我了解,有两种可能的方法:

1)运行两个不同的查询:

-- get user data and lock that row
SELECT some_column FROM users WHERE id = 2 FOR UPDATE INTO my_var;

-- just lock another rows
SELECT some_column FROM users WHERE id IN(4,7) FOR UPDATE;

2)使用一个查询,带有 CTE 和“假”更新,例如:

WITH t AS(
    UPDATE users 
    SET some_column = some_column 
    WHERE id IN(2,4,7)
    returning some_column
)
SELECT some_column FROM t WHERE id = 2
INTO my_var;

那么,哪种方式更合适呢?或者可能有更好的方法?

4

2 回答 2

1

我会使用 CTE,但没有真正的更新:

样本表和数据:

t=# create table su(i int);
CREATE TABLE
t=# insert into su values(1),(2),(3),(4);
INSERT 0 4

选择更新三键返回一键:

begin; 
with l as (select * from su where i in (1,2,4) for update)
select * from l where i = 2;
BEGIN
 i
---
 2
(1 row)

试图:

begin; update su set i=i where i = 1;

在不同的会话中等待上面的事务完成,而 withwhere i = 1没有。并且第一个事务中的 SQL 只返回where i = 2

于 2018-01-23T08:11:19.337 回答
1

第二种解决方案更糟糕,因为它执行空闲更新。如果您想在单个查询中执行此操作,请使用SELECT ... FOR UPDATE:

WITH t AS (
    SELECT id, some_column
    FROM users
    WHERE id IN(2,4,7)
    FOR UPDATE
)
SELECT some_column 
FROM t 
WHERE id = 2;
于 2018-01-23T08:12:42.013 回答