Skip to content

.NET Timeout expired

🏷️ FluentData .NET .NET Core

定时任务中经常出现 Timeout 异常。数据库是 SqlServer,DAO 使用的 FluentData

.NET Core 中的异常信息:

txt
System.Data.SqlClient.SqlException (0x80131904): Timeout 时间已到。在操作完成之前超时时间已过或服务器未响应。 ---> System.ComponentModel.Win32Exception (0x80004005): 等待的操作过时。
   在 Framework.Data.ExecuteQueryHandler.HandleQueryException(Exception exception)
   在 Framework.Data.ExecuteQueryHandler.ExecuteQuery(Boolean useReader, Action action)
   在 Framework.Data.DbCommand.QueryMany[TEntity,TList](Action`2 customMapper)
   在 Framework.Data.DbCommand.QueryMany[TEntity](Action`2 customMapper)

.NET Framework 中的异常信息:

txt
Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
   at Framework.Data.ExecuteQueryHandler.HandleQueryException(Exception exception) in \Framework.Data\Command\Handlers\ExecuteQueryHandler.cs:line 107
   at Framework.Data.ExecuteQueryHandler.ExecuteQuery(Boolean useReader, Action action) in \Framework.Data\Command\Handlers\ExecuteQueryHandler.cs:line 26
   at Framework.Data.DbCommand.QueryMany[TEntity,TList](Action`2 customMapper) in \Framework.Data\Command\PartialClasses\QueryMany.cs:line 19
   at Octopus.DAL.DAL_ORD_CharteredBusOrder.QueryToAuditAndOverdueNoAuditListForService() in \Octopus.DAL\T_ORD\T_ORD_CharteredBusOrder.DAL.cs:line 89
   at Octopus.BLL.Jobs.CT_SYS_JOB_AutoCharteredBusOrder.DoProcess_AutoCancel(String siteGuid) in \Octopus.BLL\Jobs\CT_SYS_JOB_AutoCharteredBusOrder.cs:line 24

经调查这个异常是由于 SQL 文执行超时导致的。
执行的超时时间由 IDbCommand.CommandTimeout 属性决定,默认值为 30 秒。

导致超时的原因并不是因为数据过多(数据很少),怀疑是在查询数据的同时,有别的应用也在同步更新数据导致的(并没有死锁,只是更新导致的查询被阻塞)。

这种情况下可采取的对策:

  1. 查询 SQL 文中增加 WITH(NOLOCK)WITH(READPAST) 关键字来防止查询被阻塞。

    其它的 WITH 关键字可以参考 => WITH(XLOCK)

  2. 延长查询超时时间。FluentData 中通过 IDbContext.CommandTimeout 方法设置超时时间。

    csharp
    var db = new DbContext().ConnectionString(CONN_STR, new SqlServerProvider()).CommandTimeout(60);