代码需要时间,因系统而异

时间:2014-11-05 12:01:19

标签: asp.net sql-server vb.net command-timeout

过去15天我遇到了问题。我有一个包含do-while循环的代码,里面有4个for循环。在每个循环中调用以下函数。

Public Function retds1(ByVal SPName As String, ByVal conn As SqlConnection, Optional ByVal ParameterValues() As Object = Nothing) As DataSet
    dconn = New SqlConnection(ConfigurationManager.ConnectionStrings("webriskpro").ConnectionString)
    Try
        sqlcmd = New SqlCommand
        ds = New DataSet
        If dconn.State = ConnectionState.Open Then dconn.Close()
        sqlcmd = New SqlCommand(SPName, dconn)
        sqlcmd.CommandType = CommandType.StoredProcedure
        dconn.Open()
        SqlCommandBuilder.DeriveParameters(sqlcmd)
        If Not ParameterValues Is Nothing Then
            For i As Integer = 1 To ParameterValues.Length
                sqlcmd.Parameters(i).Value = ParameterValues(i - 1)
            Next
        End If
        da = New SqlDataAdapter(sqlcmd)
        da.Fill(ds)
    Catch ex As Exception
        send_prj_err2mail(ex, SPName, "")
    Finally
        dconn.Close()
    End Try
    Return ds
End Function

现在的问题是 1)在我的本地系统中,我得到“超时已过期。在操作完成之前超时时间已过,或者服务器没有响应”错误。所以我将功能更改为以下内容。(即)我添加了CommandTimeout = 0

Public Function retds1(ByVal SPName As String, ByVal conn As SqlConnection, Optional ByVal ParameterValues() As Object = Nothing) As DataSet
    dconn = New SqlConnection(ConfigurationManager.ConnectionStrings("webriskpro").ConnectionString)
    Try
        sqlcmd = New SqlCommand
        ds = New DataSet
        If dconn.State = ConnectionState.Open Then dconn.Close()
        sqlcmd = New SqlCommand(SPName, dconn)
        sqlcmd.CommandType = CommandType.StoredProcedure
        sqlcmd.CommandTimeout = 0
        dconn.Open()
lp:
        SqlCommandBuilder.DeriveParameters(sqlcmd)
        If Not ParameterValues Is Nothing Then
            For i As Integer = 1 To ParameterValues.Length
                sqlcmd.Parameters(i).Value = ParameterValues(i - 1)
            Next
        End If
        da = New SqlDataAdapter(sqlcmd)
        da.SelectCommand.CommandTimeout = 0
        da.Fill(ds)
    Catch ex As Exception
        If ex.Message.ToString.Contains("Timeout expired") Then
            GoTo lp
        End If
        send_prj_err2mail(ex, SPName, "")
    Finally
        dconn.Close()
    End Try
    Return ds
End Function

2)但是发生的事情是“Timeout expired”异常仍然存在。通过捕获它将解决问题。但整个过程需要1个小时。

3)服务器机器也存在同样的问题。所以我们改变了服务器。现在在备份服务器中,整个代码只需3分钟。但是我本地计算机和主服务器中的相同代码需要30多分钟。

添加了:

连接字符串

<add name="webriskpro" connectionString="Data Source=TECH01\SQL2005;Initial Catalog=webriskpro1;User ID=sa;Password=#basix123; pooling=false;connection timeout=600;"/>

我有两个问题。

  1. 为什么“超时已过期..”仅来自我的本地系统和主服务器机器,而不是来自备份服务器机器?

  2. 备份服务器所花费的时间仅为3分钟。但在我的本地系统和主服务器上,它大约需要30分钟。(所有都有相同的来源,数据库)。

  3. 更新

    我已经在sql Profiler中检查过程。由于循环没有限制,我们不知道它迭代了多少次。对于前几次迭代,持续时间低于120.然后在相同的SP的某个地方,持续时间是13000,1200和那样。是什么导致了这个?

    以下内容在sql Profiler中显示,即使我在我的存储过程中设置了Arithabort

    -- network protocol: Named Pipes
    set quoted_identifier on
    set arithabort off
    set numeric_roundabort off
    set ansi_warnings on
    set ansi_padding on
    set ansi_nulls on
    set concat_null_yields_null on
    set cursor_close_on_commit off
    set implicit_transactions off
    set language us_english
    set dateformat mdy
    set datefirst 7
    set transaction isolation level read committed
    

    有人能告诉我原因是什么吗?

1 个答案:

答案 0 :(得分:1)

我认为你不应该使用CommandTimeout = 0。这将使您的脚本无限期地等待成功连接,即使这种情况永远不会发生。

我建议你在第二个解决方案中建立一个重试循环。只将CommandTimeout保持在合理的值。

此外,您应该调查连接失败的原因。也许您的服务器已达到其最大SQL连接数?也许您可以在SQL服务器日志中找到更多有用的信息。