.NET Timeout expired
定时任务中经常出现 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 秒。
导致超时的原因并不是因为数据过多(数据很少),怀疑是在查询数据的同时,有别的应用也在同步更新数据导致的(并没有死锁,只是更新导致的查询被阻塞)。
这种情况下可采取的对策:
查询 SQL 文中增加
WITH(NOLOCK)
或WITH(READPAST)
关键字来防止查询被阻塞。其它的
WITH
关键字可以参考 =>WITH(XLOCK)
。延长查询超时时间。FluentData 中通过
IDbContext.CommandTimeout
方法设置超时时间。csharpvar db = new DbContext().ConnectionString(CONN_STR, new SqlServerProvider()).CommandTimeout(60);