代码之家  ›  专栏  ›  技术社区  ›  Oto Shavadze

锁定多行,但仅获取一行作为返回结果

  •  0
  • Oto Shavadze  · 技术社区  · 8 年前

    我需要锁定多行,但只获取一行作为返回结果,例如锁定用户: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;
    

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

    2 回复  |  直到 8 年前
        1
  •  1
  •   Vao Tsun    8 年前

    我会使用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;
    

    在另一个会话中等待上述事务完成 where i = 1 没有。第一个事务中的SQL仅返回 where i = 2

        2
  •  1
  •   klin    8 年前

    第二种解决方案更糟糕,因为它执行空闲更新。 如果要在单个查询中执行此操作,请使用 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;