You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

为何node-pg中UPDATE无法设置更晚的ended_at时间?

问题分析:ended_at时间与事务开始时间一致的原因

问题场景

使用node-pg执行以下PL/pgSQL脚本:

await db.query(
`DO $$ 
 DECLARE 
     pbid INT;
 BEGIN 
     INSERT INTO public.bp(process_id) SELECT ${ID} RETURNING id INTO pbid;
     COMMIT;
     REFRESH MATERIALIZED VIEW public.vm WITH DATA;
     UPDATE public.bp SET under_process = FALSE, ended_at = now() WHERE id = pbid;
 END;$$;`
);

脚本执行正常,但ended_at字段始终等于事务开始时间,而物化视图刷新过程耗时约2分钟,且已禁用会设置new.ended_at := now()的触发器。

核心原因

PostgreSQL中now()(包括CURRENT_TIMESTAMP)函数的返回值是事务启动时的时间戳,在整个事务执行周期内保持固定不变,不会随实际时间推移更新。

尽管脚本中显式写了COMMIT,但标准PL/pgSQL的DO块默认作为单个事务执行(若你的环境未因显式COMMIT报错,可能是特殊配置,但不影响时间戳逻辑)。UPDATE语句中的now()调用,本质上还是使用事务启动时的时间,因此即使中间物化视图刷新耗时2分钟,ended_at依然和事务开始时间一致。

解决方案

若需要记录UPDATE语句实际执行时的时间,应使用clock_timestamp()函数——它会返回当前的实际系统时间,而非事务启动时间。修改后的UPDATE语句如下:

UPDATE public.bp SET under_process = FALSE, ended_at = clock_timestamp() WHERE id = pbid;

内容的提问来源于stack exchange,提问作者user1889017

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.05 13:16:01