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

Flutter API幂等接口处理:连接超时引发重复请求问题

支付后商品购买API超时的重复下单问题

按钮点击流程:先调用支付API完成用户向我方转账,随后调用商品购买API。当前存在的问题:

  • 支付API可正常执行,但商品购买API可能出现连接超时,分两种场景:
    1. 超时后用户未获得商品
    2. 超时后用户已获得商品,但我方未收到购买成功响应(对方先发放商品再返回响应),无法确认购买状态
  • 现有重试函数无限制递归调用,极易导致用户被重复下单,代码如下:
Future<Response> testDisconnect(back) async {
    debugPrint("meeow");
    debugPrint(back);
    try {
      return await dio.post("apiurl",
          data: {"me": ",e"},
          options: Options(
            headers: {
              'Content-Type': 'application/json',
              'Accept': 'application/json'
            },
          ));
    } on DioException catch (e) {
      debugPrint(e.type.toString());
      return testDisconnect(back);
    }
  }

优化方案

1. 给重试添加次数限制与退避策略

取消无限制递归,设定最大重试次数,同时采用指数退避策略(每次重试间隔递增),避免短时间内重复请求加重服务端压力,降低重复下单风险。

修改后的示例代码:

Future<Response> testDisconnect(String back, {int retryCount = 0, int maxRetries = 3}) async {
  debugPrint("meeow");
  debugPrint(back);
  try {
    return await dio.post("apiurl",
        data: {"me": ",e"},
        options: Options(
          headers: {
            'Content-Type': 'application/json',
            'Accept': 'application/json'
          },
        ));
  } on DioException catch (e) {
    debugPrint(e.type.toString());
    // 仅针对连接超时/连接错误进行重试
    if (e.type == DioExceptionType.connectionTimeout || e.type == DioExceptionType.connectionError) {
      if (retryCount < maxRetries) {
        // 指数退避:间隔依次为1s、2s、4s
        await Future.delayed(Duration(seconds: 1 << retryCount));
        return testDisconnect(back, retryCount: retryCount + 1, maxRetries: maxRetries);
      }
    }
    // 超出重试次数或非可重试错误,直接抛出异常
    throw e;
  }
}

2. 实现幂等请求机制

要求商品购买API支持幂等,确保相同请求多次调用仅产生一次效果:

  • 每次发起购买请求时,生成唯一requestId(如UUID),作为请求参数传入
  • 对方服务维护已处理requestId列表,收到重复请求时直接返回历史成功响应,不再重复发放商品

3. 增加状态查询前置步骤

当购买API超时后,优先调用商品状态查询API:

  • 若查询到用户已获得商品,直接终止流程
  • 若查询到未获得商品,再执行有限次数的重试
  • 若查询API也超时,再触发退避重试逻辑

4. 本地记录请求状态

发起购买请求前,在本地存储(如数据库、SharedPreferences)记录requestId与请求状态(待处理/处理中/成功/失败):

  • 请求发起时标记为“处理中”
  • 收到成功响应后更新为“成功”
  • 超时后先校验本地状态,结合查询API结果判断是否重试,避免重复发起请求

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.07 19:31:16