解决 SQL 查询超时错误

Posted

技术标签:

【中文标题】解决 SQL 查询超时错误【英文标题】:Solving a timeout error for SQL query 【发布时间】:2011-10-05 12:27:34 【问题描述】:

我收到此错误:

超时。在操作完成之前超时时间已过或服务器没有响应。

我知道已经有指南可以帮助解决这个问题,但它们对我不起作用。我缺少什么或者我应该在我的 C# 程序中将代码添加到这些 SQL 语句的什么位置:

String sql = project1.Properties.Resources.myQueryData;

SqlDataAdapter sqlClearQuestDefects = new SqlDataAdapter(sql,
    "Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa");

DataSet lPlanViewData = new DataSet();
sqlClearQuestDefects.Fill(lPlanViewData, "PlanViewData");

我在这一行收到超时错误:

SqlDataAdapter sqlClearQuestDefects = new SqlDataAdapter(sql, 
    "Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa");

【问题讨论】:

这听起来像是连接超时,这表明您无法连接到数据库。 嗯,我大多数时候都正确连接到数据库,只是偶尔会收到此错误。 那很正常。如果它超时一次,然后当你再次执行它时,你的第一个请求就会在 TCP/IP 网络的狂野边界中丢失。我会简单地将创建 SqlDataAdapter 的代码包装在一个 try-catch 中,在向用户显示错误之前循环几次重试。 请在适配器命令对象属性中设置连接超时属性。默认为 60 秒。 【参考方案1】:
SqlDataAdapter adp = new SqlDataAdapter();
adp.SelectCommand.CommandTimeout = 0;  // Set the Time out on the Command Object

【讨论】:

不应该是更改ConnectionTimeout来解决这个问题吗? 当代码尝试从命令对象中填充数据时发生超时,因此我们必须设置命令超时属性。 SqlCommand 对象下也存在相同的属性。同样的例外,同样的修复。谢谢!【参考方案2】:

您正在尝试连接到 SQL Server,它所花费的时间比 ADO.NET 愿意等待的时间长。

尝试使用 SQL Server Management Studio 使用相同的用户名和密码连接到同一台服务器。如果您收到相同的错误,则说明您的连接字符串有问题,您指定的服务器未运行,或者您无法通过您所在的网络访问服务器(可能您使用的是公共 IP试图进入内部服务器名称的地址)。我想不出你会在 SSMS 中输入完全相同的服务器和凭据并连接,然后在 ADO.NET 中执行相同操作并失败的场景。

如果您的网络速度较慢,您可以尝试增加超时值。但是,如果要建立连接,它应该会很快发生。

查看您的 SQL Native Client 设置和服务器上的 SQL Server 设置。有一个允许协议的部分; SQL 可以使用多种协议进行连接。通常,您需要 TCP/IP 用于网络上的服务器,而 Named Pipes 用于运行在您自己计算机上的服务器。

编辑您的评论:哦,这很正常;一直在发生。在 TCP 网络上,数据包有时会“碰撞”,或者在传输过程中“丢失”。这是包交换技术的一个已知弱点,在大多数情况下由 TCP 协议本身管理。一种不容易检测到的情况是初始连接请求在随机播放中丢失。在这种情况下,服务器不知道有请求,客户端也不知道没有收到他们的请求。所以,客户所能做的就是放弃。

为了使您的程序更加健壮,您所要做的就是预期一两次失败,然后重新尝试您的请求。这是一个基本算法:

SqlDataAdapter sqlClearQuestDefects;

short retries = 0;
while(true)

    try
    
       sqlClearQuestDefects = new SqlDataAdapter(sql, "Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa");
         break;
    
    catch(Exception)
    
       retries++;
         //will try a total of three times before giving up
       if(retries >2) throw;    
    

【讨论】:

我将如何增加此代码的超时值? 不是直接将连接和 SQL 字符串指定给 DataAdapter,而是使用允许您指定超时的 conn 字符串创建一个 SqlConnection,然后将此 SqlConnection 和 sql 字符串赋予一个新的SqlCommand,然后将 SqlCommand 赋予新的 SqlDataAdapter。还有几个步骤,但您可以访问连接和命令对象的所有属性,包括超时设置。【参考方案3】:

由于(尚未)其他答案中没有提到增加连接超时的确切命令 - 如果您确实确定需要增加连接超时,您可以在连接字符串中执行以下操作:

 Data Source=ab;Initial Catalog=ac;User ID=ad; Password =aa; Connection Timeout=120

其中 120 = 120 秒。我记得默认是 20 或 30。

【讨论】:

我的行出现超时错误:sqlClearQuestDefects.Fill(lPlanViewData, "PlanViewData");我将如何为此增加超时值?谢谢!【参考方案4】:

这可能是您的数据库的连接问题,例如,如果您有以下连接字符串:

"Data Source=MyDatabaseServer...

那么你需要确保:

机器 MyDatabaseServer 已连接到网络,可从您运行应用程序的机器(名称为“MyDatabaseServer”)访问 数据库服务器正在MyDatabaseServer 上运行 MyDatabaseServer 上的数据库服务器配置为接受来自远程计算机的连接 本地计算机和MyDatabaseServer 上的防火墙设置均已正确设置为允许 SQL Server 连接通过 您的用户名/密码等...正确

您还可以尝试使用客户端计算机上的 SQL Server Management Studio 连接到给定的数据库实例作为诊断步骤。

有很多文章解决了 SQL Server 连接问题 - 在 Google 上搜索出现或失败的特定错误消息作为Server Fault 上的特定问题

【讨论】:

【参考方案5】:

最近遇到这个问题,找到resolution that worked for me。

顺便说一句,设置Timeout = 0有助于避免异常,但是执行时间不合理,而手动执行存储过程需要几秒钟。

底线: 我将SET IMPLICIT_TRANSACTIONS OFF 添加到用于填充数据集的存储过程中。

来自 MSDN:

用于 SQL Server 的 SQL Server Native Client OLE DB 提供程序和 SQL Server Native Client ODBC 驱动程序自动设置 连接时将 IMPLICIT_TRANSACTIONS 设置为 OFF。放 IMPLICIT_TRANSACTIONS 对于与 SQLClient 托管提供程序,并用于通过接收的 SOAP 请求 HTTP 端点。 [...] 当 SET ANSI_DEFAULTS 为 ON 时,SET IMPLICIT_TRANSACTIONS 为 ON。

所以我相信在我的情况下,默认值不是必需的。 (我无法检查。在 SQL 服务器上没有足够的权限)。但是将这一行添加到我的 SP 中解决了这个问题。

重要提示:在我的情况下,我不需要事务,因此取消隐式事务设置没有问题。如果在您的情况下交易是必须的,您可能不应该使用此解决方案。

【讨论】:

以上是关于解决 SQL 查询超时错误的主要内容,如果未能解决你的问题,请参考以下文章

c#sql运行语句调整30秒超时

运行多服务器 SQL Server 查询时出现超时错误

如何解决间歇性 SQL 超时错误

在 SQL Server 2008 中执行视图时出现“超时已过期”错误

使用MySQL Workbench查询超时的错误

Perl在使用警报超时时出现分段错误