首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >是否需要更新中的CTE中的更新锁显式?

问是否需要更新中的CTE中的更新锁显式?
EN

Database Administration用户
提问于 2022-03-14 06:18:40
回答 1查看 1.9K关注 0票数 5

在Postgres 13中,我有一个经常更新的表。但是,更新查询相当复杂,多次使用相同的值。因此,使用CTE似乎是一件非常合乎逻辑的事情。

一个简化的示例如下所示:

代码语言:javascript
复制
WITH my_cte AS (
    SELECT
          my_id,
          CASE WHEN my_value1 > 100 THEN 50 ELSE 10 END AS my_addition     
    FROM my_table      
    WHERE my_id = $1
)
UPDATE my_table
        SET my_value1 = my_table.my_value1 + my_cte.my_addition,
            my_value2 = my_table.my_value2 + my_cte.my_addition
FROM my_cte
WHERE my_table.my_id = my_cte.my_id

现在我想知道:如果在CTE中的SELECT和UPDATE之间,表由另一个查询更新,从而更改my_value1,那么当UPDATE发生时,my_addition的计算就会变得过时和错误。会否出现这种情况呢?或者Postgres是否自动设置隐式锁?

如果Postgres在这里没有魔法,我需要自己来处理:在CTE的FOR UPDATE中做SELECT就足够了吗?

对不起,如果我在这里没有说清楚:我并不想“看到”那些并发修改,我想阻止它们--即,一旦完成了SELECT的计算,在UPDATE完成之前,其他任何查询都不会修改这一行。

在现实生活中,我在CASE WHEN my_value1 > 100 THEN 50 ELSE 10 END中嘲笑的东西大约有20行长,我需要在UPDATE中的大约5个地方使用它。因为我是“不要重复自己”的忠实粉丝,所以我认为CTE是可行的。或者,是否有更好的方法来避免在没有CTE的UPDATE中复制和粘贴?

EN

回答 1

Database Administration用户

发布于 2022-03-14 20:10:38

如果要防止并发语句在更新前修改CTE选择的行,则需要在CTE中使用SELECT ... FOR NO KEY UPDATE。

票数 1
EN
页面原文内容由Database Administration提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://dba.stackexchange.com/questions/308688

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档