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

RDS Aurora PostgreSQL 15.2更新subscription_id字段异常求助

Aurora PostgreSQL 15.2 UPDATE返回结果与实际数据不符问题排查

问题描述

使用RDS Aurora PostgreSQL 15.2时出现异常:首次执行UPDATE语句可正常更新wallet表的subscription_id字段;第二次执行时,返回结果显示字段已更新为新值,但实际数据库中该字段被清空。两次请求的payload均包含有效的subscription_id(仅值不同),预期两次执行均应正常更新字段值。

表结构

CREATE TABLE IF NOT EXISTS "wallet" (
    id SERIAL PRIMARY KEY,
    user_id INTEGER REFERENCES "user" (id) ON DELETE CASCADE UNIQUE,
    customer_id VARCHAR(255) NOT NULL,
    subscription_id VARCHAR(255) DEFAULT NULL,
    created_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP,
    updated_at TIMESTAMP DEFAULT CURRENT_TIMESTAMP
);

执行的UPDATE代码

await client.query('UPDATE "wallet" SET subscription_id = $1, updated_at = CURRENT_TIMESTAMP WHERE user_id = $2 RETURNING *',[subscription_id, user_id])

执行返回结果

第一次执行返回:

response.rows[0] = {"id":1,"user_id":1,"customer_id":"cus_OJNfP0Mu1EYale","subscription_id":"sub_1NqZVsJw0oI6B3daTpPVYntu","created_at":"2023-07-25T20:50:51.531Z","updated_at":"2023-09-15T09:44:42.161Z"}

第二次执行返回:

response.rows[0] ={"id":1,"user_id":1,"customer_id":"cus_OJNfP0Mu1EYale","subscription_id":"sub_1NqZWBJw0oI6B3daGKkR98K1","created_at":"2023-07-25T20:50:51.531Z","updated_at":"2023-09-15T09:45:01.986Z"}

注:第二次执行后,实际数据库中subscription_id字段值被清空,与返回结果不一致。

排查方向

  • 事务提交验证:确认第二次UPDATE所在的事务是否正常提交。若代码中存在事务控制逻辑,检查是否有未捕获的异常导致事务回滚,或者遗漏了commit操作。RETURNING返回的是事务内的快照值,若事务未提交,数据库不会持久化该变更。
  • 触发器/规则检查:查询wallet表是否存在UPDATE相关触发器:
    SELECT tgname, pg_get_triggerdef(t.oid) FROM pg_trigger t WHERE tgrelid = 'wallet'::regclass AND NOT tgisinternal;
    
    若存在触发器,检查其函数逻辑是否在更新后将subscription_id重置为null。
  • 参数绑定有效性:验证第二次执行时subscription_id参数是否正确传入。可通过打印参数值、开启数据库SQL日志(设置log_statement = 'all')确认实际执行的SQL中$1参数的真实值。
  • 读写分离与同步延迟:若使用Aurora读写分离架构,检查查询实际数据时是否访问了只读节点(数据未同步),需确保验证数据时直接访问主节点。
  • 并发更新冲突:检查是否有其他会话或进程同时更新该条user_id=1的记录,可通过查询pg_locks表查看锁定情况:
    SELECT * FROM pg_locks WHERE relation = 'wallet'::regclass AND pid != pg_backend_pid();
    

解决方案建议

  1. 手动执行验证:直接在数据库主节点执行第二次的UPDATE语句,随后查询字段值:
    UPDATE "wallet" SET subscription_id = 'sub_1NqZWBJw0oI6B3daGKkR98K1', updated_at = CURRENT_TIMESTAMP WHERE user_id = 1 RETURNING *;
    SELECT subscription_id FROM "wallet" WHERE user_id = 1;
    
    若手动执行结果正常,问题出在代码层面;若结果仍不符,需排查数据库端配置或触发器。
  2. 代码事务检查:梳理代码中的事务逻辑,确保UPDATE操作后事务正常提交,无异常回滚情况。
  3. 触发器逻辑排查:若存在触发器,仔细检查触发器函数的条件分支,确认是否存在针对第二次更新的异常处理逻辑导致字段被清空。
  4. 日志分析:开启数据库语句日志,记录所有执行的SQL,对比两次UPDATE的参数差异,定位问题根源。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 01:52:53