1. 程式人生 > >Timeout expired. The timeout period elapsed prior to completion of the operation or the server is no

Timeout expired. The timeout period elapsed prior to completion of the operation or the server is no


今天碰到了一個查詢異常問題,上網查了一下,感謝原創和譯者

如果你使用的資料庫連線類是 the Data Access Application Blocks "SqlHelper" 或者 SqlClient Class , 你在執行一個很費時的SQL 操作時候,可能就會碰到下面的超時異常。

---------------------------

---------------------------
Timeout expired.  The timeout period elapsed prior to completion of the operation or the server is not responding.
---------------------------
OK  
---------------------------

你會說,我在連線字串中已經 設定了 Connect Timeout=80000 ,並且資料庫中超時連線也是設定的值是一個很大的值。為啥到了30秒,仍然超時了呢??

這是因為:
你的設定並沒有問題,是你混淆了  SqlCommand.CommandTimeout  和 SqlConnection.ConnectionTimeout 這兩個的區別了。
你的連線字串中的超時只是設定的 SqlConnection.ConnectionTimeout 的值,而不是設定的 SqlCommand.CommandTimeout 的值。
SqlHelper 中並沒有 SqlCommand.CommandTimeout 的相關設定。需要你自己設定。

下面是兩個的比較:

SqlCommand.CommandTimeout
獲取或設定在終止執行命令的嘗試並生成錯誤之前的等待時間。
等待命令執行的時間(以秒為單位)。預設為 30 秒。


SqlConnection.ConnectionTimeout
獲取在嘗試建立連線時終止嘗試並生成錯誤之前所等待的時間。
等待連線開啟的時間(以秒為單位)。預設值為 15 秒。

這個問題可以算是 SqlHelper 設計的時候,一個考慮不周的地方吧。
SqlCommand.CommandTimeout 的預設值是30,對於我寫的大多數程式來說,這個值足夠了。所以一直都沒有發現SqlHelper的這個問題。今天在查本地一臺比較差的機子上生成一個超長帖子(近4000個回覆)無響應的問題時候,才發現SQLHelper 存在的這個問題。

把command的Timeout屬性設定一下就ok了!

/// <summary>
    /// 執行查詢語句,返回DataTable
    /// </summary>
    /// <param name="SQLString">查詢語句</param>
    /// <param name="commTime">設定查詢Timeout</param>
    /// <returns>用於複雜查詢</returns>
    public static DataTable GetDataTable(string SQLString,int commTime)
    {
        string connectionString = System.Configuration.ConfigurationManager.AppSettings["connectionString"];
        using (System.Data.SqlClient.SqlConnection connection = new System.Data.SqlClient.SqlConnection(connectionString))
        {
            DataTable dt = new DataTable();
            try
            {
                connection.Open();
                System.Data.SqlClient.SqlDataAdapter da = new System.Data.SqlClient.SqlDataAdapter();
                System.Data.SqlClient.SqlCommand comm = new System.Data.SqlClient.SqlCommand(SQLString, connection);
                comm.CommandTimeout = commTime;
                da.SelectCommand = comm;
                da.Fill(dt);
            }
            catch (System.Data.SqlClient.SqlException ex)
            {
                throw new Exception(ex.Message);
            }
            return dt;
        }
    }