Sil*_*ght 280 c# asp.net timeout sqlcommand sql-server-2008-r2
我的网站上有很多用户(每天20000-60000),这是一个移动文件的下载站点.我可以远程访问我的服务器(Windows Server 2008-R2).
我之前收到"服务器不可用"错误,但现在看到连接超时错误.
我不熟悉这个 - 它为什么会发生,我该如何解决?
完整错误如下:
'/'应用程序中的服务器错误.超时已过期.操作完成之前经过的超时时间或服务器没有响应.该语句已终止.描述:执行当前Web请求期间发生未处理的异常.请查看堆栈跟踪以获取有关错误及其源自代码的位置的更多信息.
异常详细信息:System.Data.SqlClient.SqlException:超时已过期.操作完成之前经过的超时时间或服务器没有响应.该语句已终止.
来源错误:
在执行当前Web请求期间生成了未处理的异常.可以使用下面的异常堆栈跟踪来识别有关异常的起源和位置的信息.
堆栈跟踪:
[SqlException(0x80131904):超时已过期.操作完成之前经过的超时时间或服务器没有响应.语句已终止.]
System.Data.SqlClient.SqlConnection.OnError(SqlException异常,Boolean breakConnection
)+404
System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()+ 412 System.Data.SqlClient.TdsParser.Run(RunBehavior runBehavior ,SqlCommand cmdHandler,SqlDataReader dataStream,BulkCopySimpleResultSet bulkCopyHandler,TdsParserStateObject stateObj)+1363
System.Data.SqlClient.SqlCommand.FinishExecuteReader(SqlDataReader ds,RunBehavior runBehavior,String resetOptionsString)+6387741
System.Data.SqlClient.SqlCommand.RunExecuteReaderTds(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,Boolean async)+6389442
System.Data.SqlClient.SqlCommand.RunExecuteReader(CommandBehavior cmdBehavior,RunBehavior runBehavior,Boolean returnStream,String method,DbAsyncResult result)+538
System.Data.SqlClient.SqlCommand.InternalExecuteNonQuery(DbAsyncResult result, String methodName,Boolean sendToPipe)+689
System.Data.SqlClient.SqlCommand.Execu teNonQuery()+ 327
NovinMedia.Data.DbObject.RunProcedure(String storedProcName,IDataParameter []参数,Int32和rowsAffected)+209
DataLayer.OnlineUsers.Update_SessionEnd_And_Online(Object Session_End,Boolean Online)+440
NiceFileExplorer.Global.Application_Start(Object sender,EventArgs e)+163[HttpException(0x80004005):超时已过期.操作完成之前经过的超时时间或服务器没有响应.该语句已被终止.]
System.Web.HttpApplicationFactory.EnsureAppStartCalledForIntegratedMode(HttpContext context,HttpApplication app)+4052053
System.Web.HttpApplication.RegisterEventSubscriptionsWithIIS(IntPtr appContext,HttpContext context,MethodInfo [] handlers)+191
System.Web.HttpApplication. InitSpecial(HttpApplicationState状态,MethodInfo的[]处理程序,IntPtr的appContext,HttpContext的上下文)352
System.Web.HttpApplicationFactory.GetSpecialApplicationInstance(IntPtr的appContext,HttpContext的上下文)407
System.Web.Hosting.PipelineRuntime.InitializeApplication(IntPtr的appContext)375[HttpException(0x80004005):超时已过期.操作完成之前经过的超时时间或服务器没有响应.该语句已被终止.]
System.Web.HttpRuntime.FirstRequestInit(HttpContext context)+11686928 System.Web.HttpRuntime.EnsureFirstRequestInit(HttpContext context)+141 System.Web.HttpRuntime.ProcessRequestNotificationPrivate(IIS7WorkerRequest wr,HttpContext context)+4863749
编辑后编辑:
我Application_Start的Global.asax内容如下:
protected void Application_Start(object sender, EventArgs e)
{
Application["OnlineUsers"] = 0;
OnlineUsers.Update_SessionEnd_And_Online(
DateTime.Now,
false);
AddTask("DoStuff", 10);
}
Run Code Online (Sandbox Code Playgroud)
被调用的存储过程是:
ALTER Procedure [dbo].[sp_OnlineUsers_Update_SessionEnd_And_Online]
@Session_End datetime,
@Online bit
As
Begin
Update OnlineUsers
SET
[Session_End] = @Session_End,
[Online] = @Online
End
Run Code Online (Sandbox Code Playgroud)
我有两种获取在线用户的方法:
Application["OnlineUsers"] = 0; 因此,对于方法#2,我重置了所有的OnlineUsers Application_Start.该表中有超过482,751条记录.
Mar*_*len 325
看起来你的查询花费的时间比它应该的要长.从堆栈跟踪和代码中,您应该能够确切地确定查询是什么.
这种类型的超时可能有三个原因;
死锁可能很难解决,但很容易确定是否是这种情况.使用Sql Server Management Studio连接到数据库.在左窗格中,右键单击服务器节点,然后选择" 活动监视器".看看正在运行的进程.通常大多数将闲置或运行.出现问题时,您可以通过进程状态识别任何阻止的进程.如果右键单击该流程并选择详细信息,它将显示该流程执行的最后一个查询.
第二个问题将导致数据库使用次优查询计划.可以通过清除统计信息来解决:
exec sp_updatestats
Run Code Online (Sandbox Code Playgroud)
如果这不起作用,你也可以尝试
dbcc freeproccache
Run Code Online (Sandbox Code Playgroud)
当您的服务器负载很重时,不应该这样做,因为它会暂时产生很大的性能,因为所有存储过程和查询在首次执行时都会重新编译.但是,由于您有时会说出问题,并且堆栈跟踪指示您的应用程序正在启动,我认为您正在运行仅偶尔运行的查询.通过强制SQL Server不重用以前的查询计划,您可能会更好.有关如何执行此操作的详细信息,请参阅此答案.
我已经触及了第三个问题,但您可以通过手动执行查询(例如使用Sql Server Management Studio)轻松确定查询是否需要调优.如果查询需要很长时间才能完成,即使重置统计信息后,您也可能需要对其进行调整.有关这方面的帮助,您应该在新问题中发布确切的查询.
Ela*_*tep 144
在运行存储过程的代码中,您应该具有以下内容:
SqlCommand c = new SqlCommand(...)
//...
Run Code Online (Sandbox Code Playgroud)
添加这样一行代码:
c.CommandTimeout = 0;
Run Code Online (Sandbox Code Playgroud)
这将等待操作完成所需的时间.
mat*_*eek 12
虽然所有早期的回复都解决了这个问题,但并没有涵盖所有案例.
Microsoft已承认此问题并在2011年针对受支持的操作系统进行了修复,因此如果您获得堆栈跟踪如下:
Timeout expired. The timeout period elapsed prior to completion of the operation or the server is not responding.
at System.Data.SqlClient.SqlInternalConnection.OnError(SqlException exception, Boolean breakConnection)
at System.Data.SqlClient.TdsParser.ThrowExceptionAndWarning()
at System.Data.SqlClient.TdsParserStateObject.ReadSniError(TdsParserStateObject stateObj, UInt32 error)
at System.Data.SqlClient.TdsParserStateObject.ReadSni(DbAsyncResult asyncResult, TdsParserStateObject stateObj)
Run Code Online (Sandbox Code Playgroud)
您可能需要更新.NET程序集.
出现此问题是由于镜像数据库的连接重试算法中的错误.
使用重试算法时,数据提供程序等待第一次读取(SniReadSync)调用完成.该调用将发送到运行SQL Server的后端计算机,并通过将连接超时值乘以0.08来计算等待时间.但是,如果响应很慢并且在等待时间到期之前未完成第一个SniReadSync调用,则数据提供程序会错误地将连接设置为注定状态.
有关详细信息,请参阅KB 2605597
https://support.microsoft.com/kb/2605597
Has*_*eeb 10
我遇到了同样的问题,并通过在 web.config 文件中添加“连接时间”值来解决。找到 connectionStrings 并添加Connection Timeout=3600"
这是样本
<connectionStrings>
<add name="MyConn" providerName="System.Data.SqlClient" connectionString="Data Source=MySQLServer;Initial Catalog=MyDB;User ID=sa;Password=123;Connection Timeout=3600" />
</connectionStrings>
Run Code Online (Sandbox Code Playgroud)
也许它会对某些人有用.我遇到了同样的问题,在我的情况下,原因是SqlConnection被打开而没有放在我用循环调用大约2500次迭代的方法中.连接池已用尽.适当的处理解决了这个问题.
您必须设置CommandTimeout属性.您可以在DbContext子类中设置CommandTimeout属性.
public partial class StudentDatabaseEntities : DbContext
{
public StudentDatabaseEntities()
: base("name=StudentDatabaseEntities")
{
this.Database.CommandTimeout = 180;
}
protected override void OnModelCreating(DbModelBuilder modelBuilder)
{
throw new UnintentionalCodeFirstException();
}
public virtual DbSet<StudentDbTable> StudentDbTables { get; set; }
}
Run Code Online (Sandbox Code Playgroud)
我在3天左右遇到了相同的问题.我注意到我们的记录数量并不多,我们的高级开发人员在数据库中保留了2个图像和指纹.当我尝试获取这个十六进制值时需要很长时间,我计算执行我的程序的平均时间大约是38秒.默认的commandtimeout是30秒,因此它比运行我的存储过程所需的平均时间少.我将commandtimeout设置如下
cmd.CommandTimeout = 50
Run Code Online (Sandbox Code Playgroud)
并且它的工作正常,但有时如果你的查询超过50秒,它将提示相同的错误.
默认超时为 15 秒,要更改它,0 是无限制的,任何其他数字都是秒数。
在代码中
using (SqlCommand sqlCmd = new SqlCommand(sqlQueryString, sqlConnection))
{
sqlCmd.CommandTimeout = 0; // 0 = give it as much time as it needs to complete
...
}
Run Code Online (Sandbox Code Playgroud)
在您的 Web.Config 中,“命令超时 = 0;” 不超时,或低于 1 小时(3600 秒)
<add name="ConnectionString" connectionString="Data Source=ServerName;User ID=UserName;Password=Password;Command Timeout=3600;" providerName="System.Data.SqlClient" />
Run Code Online (Sandbox Code Playgroud)
如果您按照Startup.cs约定使用 ASP.NET Core,则可以像这样访问和设置查询命令超时选项:
public void ConfigureServices(IServiceCollection services)
{
services.AddDbContextPool<MyDbContext>(_ =>
{
_.UseSqlServer(Configuration.GetConnectionString("MyConnectionString"), options =>
{
options.CommandTimeout(180); // 3 minutes
});
});
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
708100 次 |
| 最近记录: |