如何在Prisma.$transaction中返回更新失败的具体ID信息
解决Prisma批量更新时提示未找到的具体ID问题
方案一:先校验ID存在性,再执行更新
这种方式更高效,先提前排查不存在的ID,避免进入事务后失败,直接给用户明确提示。
const grades = [ {id: 1, grade: '100'}, {id: 45, grade: '98'} ]; // 提取所有待更新的ID const targetIds = grades.map(el => el.id); // 查询数据库中已存在的目标ID记录 const existingStudents = await prisma.student.findMany({ where: { id: { in: targetIds } }, select: { id: true } }); // 把存在的ID存入集合,方便快速判断 const existingIds = new Set(existingStudents.map(s => s.id)); // 筛选出不存在的ID const missingIds = targetIds.filter(id => !existingIds.has(id)); // 若有不存在的ID,直接抛出自定义错误 if (missingIds.length > 0) { throw new Error(`以下ID不存在:${missingIds.join(', ')}`); } // 校验通过后,执行批量更新事务 await prisma.$transaction( grades.map(el => prisma.student.update({ where: { id: el.id }, data: { grade: el.grade } }) ) );
方案二:用交互式事务逐个处理,捕获错误
如果需要严格保证原子性(必须所有更新要么全成要么全败),可以用Prisma的交互式事务,逐个执行更新并捕获错误,最后统一抛出不存在的ID列表。
const grades = [ {id: 1, grade: '100'}, {id: 45, grade: '98'} ]; await prisma.$transaction(async (tx) => { const missingIds = []; for (const el of grades) { try { await tx.student.update({ where: { id: el.id }, data: { grade: el.grade } }); } catch (e) { // 用Prisma标准错误码判断是否为记录未找到 if (e.code === 'P2025') { missingIds.push(el.id); } else { // 其他类型错误直接抛出,终止事务 throw e; } } } if (missingIds.length > 0) { throw new Error(`更新失败,以下ID不存在:${missingIds.join(', ')}`); } });
注意点
- Prisma的
P2025是记录未找到的标准错误码,比匹配错误文本更可靠; - 方案一性能更优,减少数据库交互次数;方案二则严格遵循事务原子性,适合需要强一致性的场景。
内容的提问来源于stack exchange,提问作者Gonzalo Rocha
相关产品推荐
相关产品推荐

