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

NestJS结合TypeORM:捕获PostgreSQL save()时的unique_violation错误

数据库唯一约束冲突的处理实现

首先必须先在数据库的name字段上添加唯一约束——这是核心前提,只有数据库层面存在该约束,重复插入时才会触发unique_violation类型的错误,这比你用.some()全表遍历检查高效得多,还能避免并发场景下的竞态问题。

接下来完善你给出的代码逻辑,具体处理步骤如下:

  • 捕获QueryFailedError后,通过数据库特定的错误码判断是否为唯一约束冲突:
    • PostgreSQL:错误码是23505
    • MySQL:错误码是1062
    • SQLite:错误码是SQLITE_CONSTRAINT_UNIQUE
  • 确认是唯一约束冲突时,抛出业务友好的自定义错误;其他类型的数据库错误直接原样抛出,不做拦截。

完善后的代码示例(以PostgreSQL为例):

import { QueryFailedError } from '@nestjs/typeorm';

// 根据你使用的数据库替换对应的错误码
const UNIQUE_VIOLATION_CODE = '23505';

try {
  const newObject = await this.repository.save({
    ...newObjectDto,
  });
  return newObject;
} catch (err) {
  if (err instanceof QueryFailedError) {
    // 校验是否为唯一约束冲突错误
    if (err.driverError.code === UNIQUE_VIOLATION_CODE) {
      throw new Error('该名称已被占用,请更换其他名称');
    }
    // 其他数据库操作错误,直接抛出原错误
    throw err;
  }
  // 非数据库查询错误,原样抛出
  throw err;
}

关键提醒

  • 不要仅依赖应用层检查:哪怕你在保存前用代码查一遍数据库,高并发场景下还是可能出现两个请求同时通过检查、最终插入重复数据的情况,只有数据库的唯一约束能彻底杜绝这种问题。
  • 不同数据库的错误码差异:上面的示例用了PostgreSQL的错误码,如果你用的是其他数据库,一定要替换成对应数据库的唯一约束冲突错误码。

内容的提问来源于stack exchange,提问作者Szymon Kaszuba-Gałka

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.19 19:01:20