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

使用Polly WaitAndRetry实现数据库查询重试遇空引用异常求助

问题分析与解决方案

你的代码存在两个核心问题,导致重试逻辑未触发且抛出异常:

  1. 重试条件不匹配
    当前Polly策略仅捕获Exception,但查询返回null或ID=0属于正常返回(不会抛出异常),因此Polly不会触发重试。

  2. 返回类型不兼容
    ExecuteAsync<BatchMailLog>指定返回BatchMailLog类型,但实际执行的QueryFirstOrDefaultAsync<StageLog>返回StageLog类型,类型不匹配会引发转换异常,也就是你遇到的NullReferenceException。

修正后的代码

var parameters = new { PackageID = packageId };
var query = $"Select ID From Staging..Log Where StagePkg=@PackageID";

// 定义重试策略:捕获异常 + 检查返回结果是否无效
var retryPolicy = Policy
    .Handle<Exception>()
    .OrResult<StageLog>(result => result == null || result.ID == 0) // 新增:识别无效返回结果
    .WaitAndRetryAsync(4, retryAttempt => { // 调整重试节奏,每次等10秒,总等待40秒匹配数据库生成窗口
        var timeToWait = TimeSpan.FromSeconds(10);
        Console.WriteLine($"等待 {timeToWait.TotalSeconds} 秒后重试");
        return timeToWait;
    });

// 修正返回类型,与查询结果类型保持一致
return await retryPolicy.ExecuteAsync<StageLog>(async () => 
    await SybaseConnection.WithConnectionAsync(c => c.QueryFirstOrDefaultAsync<StageLog>(query, parameters))
);

关键调整说明

  • 新增结果校验逻辑:通过.OrResult<StageLog>(...)让Polly把“返回null”或“ID=0”判定为需要重试的场景。
  • 优化重试等待策略:将原指数退避(10秒、100秒...)改为固定10秒重试一次,重试4次总等待40秒,匹配数据库生成数据的35-45秒时间窗口。
  • 修正类型匹配问题:将ExecuteAsync<BatchMailLog>改为ExecuteAsync<StageLog>,避免类型转换异常。如果业务最终需要BatchMailLog,可在获取有效StageLog后再做字段映射。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.10 02:05:22