async/await本身不提供事务回滚能力,需通过补偿逻辑、数据库事务或saga模式实现:捕获异常后执行逆序补偿操作;同一数据库中优先用事务自动回滚;分布式场景采用saga模式协调正向与补偿操作;须注意错误传播边界,避免漏捕获或未await导致伪回滚。

async/await 本身不提供事务或回滚能力,错误回滚需要你主动设计补偿逻辑或结合支持事务的资源(如数据库事务)来实现。关键在于:捕获异常后,执行与已成功操作相反的“补偿操作”,或利用底层系统(如数据库、消息队列)的原子性与回滚机制。
用 try/catch 配合补偿操作手动回滚
适用于业务逻辑涉及多个异步步骤(如调用多个服务、写多张表),且无法依赖数据库事务的场景。核心是:每一步成功后记录状态或保存反向操作所需参数,出错时按逆序执行补偿。
- 先执行 A(如扣库存),成功后保存 undoA 所需数据(如原库存量)
- 再执行 B(如创建订单),成功后保存 undoB 所需数据(如订单 ID)
- 若 C 失败,在 catch 中依次调用 undoB、undoA
- 补偿操作也需 try/catch 并记录日志,避免补偿失败导致状态不一致
借助数据库事务自动回滚
当所有操作都在同一个数据库中(如 MySQL、PostgreSQL),优先使用事务包裹 async 操作,让数据库保证 ACID。
- 用支持事务的驱动(如 mysql2 + connection.beginTransaction(),或 TypeORM 的 QueryRunner)
- await queryRunner.startTransaction()
- 在 try 块中 await 执行多个 await save() / query(),全部成功则 commit
- catch 中调用 queryRunner.rollback(),数据库自动撤回已执行语句
- 注意:事务不能跨数据库、不能包含外部 HTTP 请求等非事务性操作
结合 Saga 模式处理分布式事务
微服务或多系统协作时,单库事务失效,Saga 是常用解法:每个服务提供正向操作和对应补偿接口,由协调器按序调用并反向补偿。
- 定义每个步骤的 do 和 undo 函数(如 paymentService.charge() 和 paymentService.refund())
- 用 async/await 顺序执行 do 步骤,任意失败则同步调用前面所有步骤的 undo
- 生产环境建议加入重试、幂等、超时控制,并持久化 Saga 状态(防止协调器宕机)
- 可基于框架如 Masstransit(.NET)或自研轻量协调器,Node.js 中可用 simple-saga 或自建状态机
避免“伪回滚”:注意 await 的错误传播边界
async/await 错误不会自动向上冒泡到外层函数,若漏写 catch 或未 await,会导致回滚逻辑被跳过。
- 不要只在最外层 try/catch —— 中间某步未 await,错误会静默丢失
- 避免在 forEach 中直接 await,应改用 for...of 或 Promise.all().catch()
- 对并行操作(如同时调用多个 API),用 Promise.allSettled() 获取全部结果,再统一判断是否需要回滚
- 必要时用 finally 清理临时资源(如释放锁、删除缓存),但注意 finally 不接收 error 参数,需提前保存 err











