在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
相关产品推荐
相关产品推荐

