-1

在过去的 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)但是发生的事情是“超时已过期”异常仍然存在。抓住它就可以解决问题。但整个过程需要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;"/>

我有 2 个问题。

  1. 为什么“超时过期..”只出现在我的本地系统和主服务器机器上,而不出现在备份服务器机器上?

  2. 备份服务器所用的代码只需要 3 分钟。但在我的本地系统和主服务器中,大约需要 30 分钟或更长时间。(都具有相同的源、数据库)。

更新:

我已经检查了 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

谁能建议我是什么原因?

4

1 回答 1

1

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

我建议构建一个重试循环,就像您在第二个解决方案中所做的那样。仅将 CommandTimeout 保持在合理的值。

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

于 2014-11-05T12:09:30.737 回答