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 } }
排查建议
针对虚假记录问题
- 排查Prisma Accelerate缓存:你使用了
@prisma/extension-accelerate,它默认会缓存查询结果,可能导致Supabase表清空后仍返回旧缓存数据。可以:- 临时移除Accelerate扩展,直接使用Prisma Client执行查询,验证问题是否消失。
- 在查询时显式禁用缓存:
const existingUpvote = await prisma.upvote.findFirst({ where: { suggestion_id, upvoter_id }, cacheStrategy: { ttl: 0 } })
- 验证Schema与表结构一致性:确认Prisma Schema中
upvote表的定义(字段类型、主键、约束等)与Supabase实际表完全匹配,避免Schema过时导致的查询异常。 - 检查数据库隔离级别:Supabase默认使用读已提交隔离级别,若手动修改过,可能出现幻读或脏读,可在Supabase控制台确认当前隔离级别。
针对偶发500错误
- 捕获完整错误日志:在Prisma操作外层添加try/catch,打印完整错误信息(包括错误码、堆栈、详细描述),500错误通常对应数据库层面的问题:
try { // 原查询/创建/删除代码 } catch (error) { console.error('操作失败详情:', JSON.stringify(error, null, 2)) throw error } - 查看Supabase数据库日志:登录Supabase控制台,进入数据库的日志页面,查找500错误对应的具体原因(如外键约束冲突、主键重复、连接超时、资源限制等)。
- 验证版本兼容性:确认Prisma版本与
@nuxtjs/supabase版本是否兼容,版本不匹配可能导致偶发的连接或操作异常。 - 改用原子操作优化逻辑:将「查-删/创」的分步逻辑改为原子操作,减少出错概率,比如用
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
相关产品推荐
相关产品推荐

