使用Prisma事务时无法触发回滚的问题排查
Prisma事务回滚问题排查与解决
第一个场景:$transaction回调内操作未回滚
你当前的代码核心问题是没有使用事务回调提供的绑定事务的Prisma客户端执行数据库操作。
Prisma的$transaction方法会向回调函数传入一个专属的事务客户端实例,所有需要纳入事务的操作必须通过这个实例执行——如果用全局的globals.prisma,操作会脱离当前事务上下文独立提交,后续抛错自然无法触发回滚。
修正后的代码示例:
await globals.prisma.$transaction(async (tx) => { // 将事务客户端tx传入SaveDetails,让内部操作基于它执行 return await o.SaveDetails(tx, taintedResponse); });
同时修改SaveDetails方法,使用传入的事务客户端完成保存:
async SaveDetails(tx, data) { // 用tx而非全局globals.prisma执行数据库操作 await tx.yourModel.create({ data }); throw new Error("Dingity!"); // 此时会触发整个事务回滚 }
第二个场景:原生SQL与Prisma语句混用不生效
Prisma依赖连接池管理数据库连接,每次$executeRawUnsafe或ORM模型操作可能从连接池获取不同的连接。你用原生begin开启的事务仅对当前连接有效,后续的Prisma语句大概率跑在另一个独立连接上,完全不受原生事务的控制,所以无论是否调用rollback,Prisma的操作都会直接持久化。
绝对不要混用原生事务语句和Prisma的ORM操作,所有事务逻辑都应该通过Prisma官方提供的$transaction方法实现,它会自动统一管理连接与事务上下文。
内容的提问来源于stack exchange,提问作者Krillegeddon
相关产品推荐
相关产品推荐

