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

Scala下两个有执行顺序要求的Future调用的错误处理与回滚实现

纯Scala 2.13原生Future实现带回滚的顺序调用方案

不需要引入第三方库,直接基于原生Future的flatMap链式调用结合Either的分支匹配即可实现需求。原生for推导式没有内置错误分支的回滚处理钩子,硬写反而会增加冗余逻辑,更推荐直接手写flatMap分支处理。

已有方法签名参考:

// 业务处理方法
def processUser(..): Future[Either[Error, UserStatus]]
def processTransactions(..): Future[Either[Error, TransactionStatus]]
// 回滚方法(可根据实际签名调整)
def unprocessUser(status: UserStatus): Future[Unit]

完整实现代码

import scala.concurrent.Future
// 注意替换为业务实际使用的ExecutionContext,不建议直接用全局默认
import scala.concurrent.ExecutionContext.Implicits.global

def runProcessFlow(user: User, ...): Future[Either[Error, Unit]] = {
  processUser(user).flatMap {
    // 规则1:processUser返回错误,直接透传错误,不调用后续transaction方法
    case Left(userError) => Future.successful(Left(userError))
    // processUser执行成功,执行transaction逻辑
    case Right(userStatus) =>
      processTransactions(...).flatMap {
        // 规则2:两个方法都执行成功,返回成功
        case Right(_) => Future.successful(Right(()))
        // 规则3:transaction执行失败,先回滚processUser的操作再返回错误
        case Left(txnError) =>
          unprocessUser(userStatus).map(_ => Left(txnError))
      }
  }
}

简化写法(使用Either.fold)

如果偏好更简洁的函数式写法,可以用Either自带的fold方法替代模式匹配,逻辑完全等价:

def runProcessFlow(user: User, ...): Future[Either[Error, Unit]] = {
  processUser(user).flatMap(
    _.fold(
      userErr => Future.successful(Left(userErr)),
      userStatus => processTransactions(...).flatMap(
        _.fold(
          txnErr => unprocessUser(userStatus).map(_ => Left(txnErr)),
          _ => Future.successful(Right(()))
        )
      )
    )
  )
}

注意事项

  • 如果需要忽略回滚方法unprocessUser自身的执行错误,避免回滚失败覆盖原始业务错误,可以给回滚方法增加异常捕获逻辑:
    unprocessUser(userStatus).recover{ case _ => () }.map(_ => Left(txnError))
    
  • 如果你需要处理Future层面抛出的非受检异常(比如方法内部直接抛异常而非返回Left),可以在对应Future后追加recover/recoverWith逻辑做兼容处理。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.10.01 08:15:02