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

Prisma删除导航数据遇写入冲突/死锁问题及优化咨询

解决Prisma删除导航数据的写冲突问题及单条删除实现

一、单条命令删除指定用户的所有导航数据

你不需要分两次执行删除操作,所有属于目标用户的导航项(无论是否为父级)都可以通过单条deleteMany语句一次性删除,直接匹配userId即可:

await this.navigation.deleteMany({
  where: {
    userId: userId
  }
})

这种写法既简化了代码,也从根源上减少了多次删除操作引发的数据库锁竞争概率。

二、解决写冲突/死锁报错

如果使用单条命令后仍遇到类似报错,可以尝试以下几种方案:

  • 用Prisma事务包裹操作:将删除逻辑放在事务中,保证操作的原子性,降低锁冲突的发生几率:
    await this.prisma.$transaction(async (tx) => {
      await tx.navigation.deleteMany({
        where: { userId: userId }
      })
    })
    
  • 调整关联的onDelete策略:如果业务逻辑允许,修改Prisma模型中parent关联的删除策略为Cascade,这样删除父级导航时会自动删除其子级(需重新生成数据库迁移):
    parent    Navigation?  @relation(name: "Navigation_children", fields: [parentId], references: [id], onDelete: Cascade, onUpdate: NoAction)
    
    注意:修改后依然推荐使用userId匹配的单条删除逻辑,这是最直接的方式。
  • 添加重试机制:针对偶发的写冲突,在代码中增加重试逻辑,通过try-catch包裹操作,失败后重试几次:
    const maxRetries = 3;
    let retries = 0;
    
    while (retries < maxRetries) {
      try {
        await this.navigation.deleteMany({
          where: { userId: userId }
        });
        break;
      } catch (error) {
        retries++;
        if (retries === maxRetries) throw error;
        await new Promise(resolve => setTimeout(resolve, 100));
      }
    }
    

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 06:42:45