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

Supabase upvote表异常:查询无记录却可删除+随机500错误求助

问题:Supabase表清空后仍返回不存在记录,且操作偶发500错误

核心异常

  • 虚假记录问题:已清空Supabase中upvote表所有记录,但业务逻辑仍能查询到不存在的记录,执行删除操作还返回成功提示。业务逻辑为「点赞前先查询记录,存在则删除,不存在则创建」,但清空表后系统始终判定存在记录并执行删除流程。
  • 偶发500错误:创建/删除upvote记录时随机出现500 internal server error,多数情况正常,已排除竞态条件问题。

已排查方向

怀疑Supabase返回旧数据,但等待许久、重启服务器后问题依旧,直接查询Supabase表确认无本地数据冲突。


使用的技术栈

"prisma": "5.17.0",
"@prisma/client": "5.17.0",
"@prisma/extension-accelerate": "^1.1.0",
"nuxt": "^3.13.0",
"@nuxtjs/supabase": "^1.3.5",

相关业务代码

const existingUpvote = await prisma.upvote.findFirst({
  where: {
    suggestion_id: suggestion_id,
    upvoter_id: userId
  }
})
console.log('**********************************')
console.log('existingUpvote', existingUpvote)

if (existingUpvote?.id) {
  // 存在则取消点赞
  console.log('**********************************')
  console.log('deleting upvote')
  console.log('existingUpvote', existingUpvote)
  const removedUpvote = await prisma.upvote.delete({
    where: {
      id: existingUpvote.id
    }
  })
  return { message: 'Upvote removed', upvote: removedUpvote, removed: true }
} else {
  // 不存在则添加点赞
  console.log('**********************************')
  console.log('creating new upvote')
  console.log('suggestion_id', suggestion_id)
  console.log('userId', userId)
  const newUpvote = await prisma.upvote.create({
    data: {
      suggestion_id: suggestion_id!,
      upvoter_id: userId
    }
  })
  return { message: 'Upvoted', upvote: newUpvote, removed: false }
}

排查建议

针对虚假记录问题

  1. 排查Prisma Accelerate缓存:你使用了@prisma/extension-accelerate,它默认会缓存查询结果,可能导致Supabase表清空后仍返回旧缓存数据。可以:
    • 临时移除Accelerate扩展,直接使用Prisma Client执行查询,验证问题是否消失。
    • 在查询时显式禁用缓存:
      const existingUpvote = await prisma.upvote.findFirst({
        where: { suggestion_id, upvoter_id },
        cacheStrategy: { ttl: 0 }
      })
      
  2. 验证Schema与表结构一致性:确认Prisma Schema中upvote表的定义(字段类型、主键、约束等)与Supabase实际表完全匹配,避免Schema过时导致的查询异常。
  3. 检查数据库隔离级别:Supabase默认使用读已提交隔离级别,若手动修改过,可能出现幻读或脏读,可在Supabase控制台确认当前隔离级别。

针对偶发500错误

  1. 捕获完整错误日志:在Prisma操作外层添加try/catch,打印完整错误信息(包括错误码、堆栈、详细描述),500错误通常对应数据库层面的问题:
    try {
      // 原查询/创建/删除代码
    } catch (error) {
      console.error('操作失败详情:', JSON.stringify(error, null, 2))
      throw error
    }
    
  2. 查看Supabase数据库日志:登录Supabase控制台,进入数据库的日志页面,查找500错误对应的具体原因(如外键约束冲突、主键重复、连接超时、资源限制等)。
  3. 验证版本兼容性:确认Prisma版本与@nuxtjs/supabase版本是否兼容,版本不匹配可能导致偶发的连接或操作异常。
  4. 改用原子操作优化逻辑:将「查-删/创」的分步逻辑改为原子操作,减少出错概率,比如用deleteMany替代先查后删:
    const deleteResult = await prisma.upvote.deleteMany({
      where: { suggestion_id, upvoter_id }
    })
    if (deleteResult.count > 0) {
      return { message: 'Upvote removed', removed: true }
    } else {
      const newUpvote = await prisma.upvote.create({
        data: { suggestion_id, upvoter_id }
      })
      return { message: 'Upvoted', upvote: newUpvote, removed: false }
    }
    
    也可以用事务包裹操作,确保数据一致性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.17 17:05:59