Sequelize create 保存日志时生成多条重复记录问题求解
Sequelize 单次调用重复落库日志的排查与解决方案
已确认业务流程仅单次触发addLog方法、且全链路完成await等待,可按以下顺序从高概率到低概率逐层排查:
一、ORM层内部逻辑排查
- 检查
LogEntity模型的钩子配置:确认是否在模型定义时注册了afterCreate/afterSave类钩子,且钩子回调中存在重复调用create的逻辑——主流程写入1次,钩子回调再写入的组合,就会生成2条完全一致的记录 - 核对Sequelize初始化配置:是否误开启了连接层自动重试写入的参数,当首次写入因为网络抖动返回非明确成功响应时,连接层会自动发起重试,由于日志表无唯一约束,重试请求会生成独立的重复记录
- 确认
create方法传入的配置项:是否误带了会触发多次写入的参数,比如错误配置的分表逻辑、批量写入拆分参数
二、上层服务链路排查
- 检查路由挂载配置:确认同一路由地址是否被重复绑定了多个处理器实例,或全局中间件层存在对同一路径的重复拦截,这类配置问题会导致单次上游请求触发多次控制器方法执行
- 排查服务运行时配置:比如nodemon热更新的监听范围配置错误、进程守护工具的多实例误启动,都会导致一次请求被多个进程实例接收处理,生成多条重复日志
- 核对中间件执行链路:确认是否在洋葱模型的前置、后置中间件中都重复挂载了
addLog的调用逻辑
三、数据库端配置排查
- 检查日志表的触发器配置:如果表上配置了AFTER INSERT触发器,且触发器逻辑是向同一张表插入相同内容的记录,就会因为嵌套触发生成2-3条完全一致的日志
- 核对数据库同步逻辑:确认是否在Sequelize的
sync流程中存在自动写入测试日志的逻辑,导致开发环境的异常触发
四、兜底解决手段
- 全链路埋点校验:在
LogEntity.create的入口位置打印入参、进程ID、精确时间戳,通过日志统计单业务操作下的实际触发次数,快速定位重复是发生在进入create方法前,还是create方法的执行流程内部 - 增加数据库层唯一约束:给日志表绑定包含Uid、操作精确时间、操作标识的联合唯一索引,从数据库层面拦截完全重复的写入请求,哪怕上层存在重复触发,也不会生成多条完全一致的脏数据
内容的提问来源于stack exchange,提问作者Moataz Lotfy
相关产品推荐
相关产品推荐

