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

在NestJS中使用Drizzle时,抛出HttpException是否会自动回滚事务?

NestJS + Drizzle 事务回滚与 HttpException 处理

分两种场景直接说明处理方式:

1. 使用 Drizzle 回调式事务(db.transaction(async (tx) => { ... }))

这种情况下,直接抛出 HttpException 就会触发自动回滚,不需要显式调用 tx.rollback()。

Drizzle 的回调式事务逻辑是:如果回调函数正常执行完毕,事务自动提交;如果回调内部抛出任何异常(包括你的 HttpException),Drizzle 会自动捕获并回滚事务,之后再把异常抛给 Nest 的全局异常处理器处理,不影响 HTTP 响应的返回。

示例代码:

async createUser(createUserDto: CreateUserDto) {
  try {
    return await this.db.transaction(async (tx) => {
      const user = await tx.insert(users).values(createUserDto).returning();
      
      if (user[0].email.includes('invalid')) {
        // 直接抛异常,Drizzle 自动回滚
        throw new HttpException('无效邮箱', HttpStatus.BAD_REQUEST);
      }
      
      return user[0];
    });
  } catch (error) {
    throw error; // 交给 Nest 返回 HTTP 响应
  }
}

2. 手动管理事务(const tx = await db.begin())

这种情况下,必须先显式调用 tx.rollback() 再抛出异常。

因为手动开启的事务完全由开发者控制,Drizzle 不会自动捕获异常来触发回滚。如果只抛 HttpException,事务会处于未提交的挂起状态,最终要么因数据库超时被强制回滚,要么后续代码意外执行 tx.commit() 导致错误数据提交。

示例代码:

async createUser(createUserDto: CreateUserDto) {
  const tx = await this.db.begin();
  try {
    const user = await tx.insert(users).values(createUserDto).returning();
    
    if (user[0].email.includes('invalid')) {
      await tx.rollback(); // 先回滚事务
      throw new HttpException('无效邮箱', HttpStatus.BAD_REQUEST);
    }
    
    await tx.commit(); // 正常提交事务
    return user[0];
  } catch (error) {
    await tx.rollback(); // 异常场景兜底回滚
    throw error;
  }
}

总结:

  • 用回调式事务:直接抛 HttpException,事务自动回滚。
  • 手动管理事务:先调用 tx.rollback() 再抛异常,确保事务正确终止。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.20 16:42:40