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

Prisma事务中传递DB对象至函数时出现事务已关闭错误

问题分析

报错Transaction already closed的核心原因是事务回调函数提前执行完毕,Prisma默认会在回调函数返回后立即关闭事务,而你的代码中有未被等待的异步操作,导致这些操作在事务关闭后才执行,从而触发错误。

具体问题点:

  1. db.case_file.update调用后使用.then处理,但没有将这个Promise返回或等待,导致事务回调不等待更新完成就继续执行。
  2. createNotesAction是异步函数,但在.then回调中调用时没有使用await,这个异步操作完全脱离了事务的控制流。
  3. 额外风险:findOneByLeadId如果是直接使用this.prisma而非事务传入的db,该查询不在事务范围内,可能导致数据不一致。
解决方案

修正代码的异步控制流,确保所有事务内的异步操作都被正确等待,同时统一使用async/await风格:

createNote = async (input: CreateSupplementalNoteInput): Promise<CaseFile> => {
  const { leadIdentifier, notes, createUserId, actor } = input;

  const createNotesAction = async (db, caseId: string) => {
    const ACTION_CODE = "UPDATENOTE";
    const ACTION_TYPE_CODE = "CASEACTION";

    const xref = await db.action_type_action_xref.create({
      data: {
        action_code: ACTION_CODE,
        action_type_code: ACTION_TYPE_CODE,
        create_user_id: createUserId,
        create_utc_timestamp: new Date(),
      },
    });

    await db.action.create({
      data: {
        case_guid: caseId,
        action_type_action_xref_guid: xref.action_type_action_xref_guid, // 需传入xref的主键字段,原代码直接传对象会报错
        actor_guid: actor,
        action_date: new Date(),
        create_user_id: createUserId,
        create_utc_timestamp: new Date(),
      },
    });
  };

  try {
    const updatedCaseFile = await this.prisma.$transaction(async (db) => {
      // 改用事务内的db执行查询,确保查询在事务中
      const caseFile = await db.case_file.findUnique({ 
        where: { lead_identifier: leadIdentifier } // 替换原findOneByLeadId逻辑,使用事务db实例
      });

      if (!caseFile) {
        throw new Error("Case file not found");
      }

      const { case_file_guid: caseIdentifier } = caseFile;

      // 等待更新操作完成
      const updatedCase = await db.case_file.update({
        where: { case_file_guid: caseIdentifier },
        data: {
          note_text: notes,
        },
      });

      // 等待createNotesAction完成,确保事务不会提前关闭
      await createNotesAction(db, caseIdentifier);

      return updatedCase;
    });

    return updatedCaseFile;
  } catch (error) {
    console.log("exception: unable to create supplemental note", error);
    throw new GraphQLError("Exception occurred. See server log for details", {});
  }
};
关键注意事项
  • 事务内必须等待所有异步操作:Prisma的$transaction会在回调函数返回的Promise resolve后提交事务,如果有未等待的异步操作,事务会提前关闭。
  • 统一使用async/await:避免混用.then和await,减少异步控制流错误。
  • 所有事务内操作使用传入的db实例:确保查询、更新、创建都在同一个事务中,避免数据不一致。
  • 注意关联字段的正确传递:关联字段需要传入对应记录的主键值,而非整个对象。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.27 03:52:46