使用Linq to SQL处理连接超时

时间:2014-07-02 11:27:48

标签: c# sql sql-server linq

我的进程后台运行了一个更新线程,使用Linq-to-SQL,每5分钟查询一次MS SQL Server 2008 R2数据库,查找要更新的记录。我会定期看到一个例外:

  

System.Data.SqlClient.SqlException(0x80131904):连接超时   过期。尝试使用时超时时间已过   登录前握手确认。这可能是因为   登录前握手失败或服务器无法响应   时间。尝试连接到此服务器时花费的持续时间   是 - [预登录]初始化= 1;握手= 15106; --->   System.ComponentModel.Win32Exception(0x80004005):等待操作   超时

重试操作的正确方法是什么?

我会像这样在DB操作块周围换一个for循环吗?

public static List<MyRecord> GetUpdatableRecords()
{
    Console.Write("Getting records with null fields...");
    var returnSet = new List<MyRecord>();
    const int retries = 5;
    using (var db = new myDataContext())
    {
        for (var i = 0; i < retries; i++)
        {
            try
            {
                returnSet = db.MyRecords.Where(p => p.businessDate == null).ToList();
                Logging.LogDebug(String.Format("Found {0} records to update!", returnSet.Count));
                break;
            }
            catch (SqlException e)
            {
                Logging.LogInfo(String.Format("SqlException.Number:     {0}", e.Number));
                Logging.LogInfo(String.Format("SqlException.ErrorCode:  {0}", e.ErrorCode));
                Logging.LogInfo(String.Format("SqlException.HResult:    {0}", e.HResult));
                Logging.LogWarn("SqlException: ", e);
                if (i == retries - 1)
                    throw;
            }
            catch (Exception e)
            {
                Logging.LogWarn("Exception: ", e);
                throw;
            }
        }
    }
    return returnSet;
}

或者我可以使用块包围整个数据上下文的for循环吗?

public static List<MyRecord> GetUpdatableRecords()
{
    Console.Write("Getting records with null fields...");
    var returnSet = new List<MyRecord>();
    const int retries = 5;
    for (var i = 0; i < retries; i++)
    {
        using (var db = new myDataContext())
        {
            try
            {
                returnSet = db.MyRecords.Where(p => p.businessDate == null).ToList();
                Logging.LogDebug(String.Format("Found {0} records to update!", returnSet.Count));
                break;
            }
            catch (SqlException e)
            {
                Logging.LogInfo(String.Format("SqlException.Number:     {0}", e.Number));
                Logging.LogInfo(String.Format("SqlException.ErrorCode:  {0}", e.ErrorCode));
                Logging.LogInfo(String.Format("SqlException.HResult:    {0}", e.HResult));
                Logging.LogWarn("SqlException: ", e);
                if (i == retries - 1)
                    throw;
            }
            catch (Exception e)
            {
                Logging.LogWarn("Exception: ", e);
                throw;
            }
        }
    }
    return returnSet;
}

1 个答案:

答案 0 :(得分:0)

正如您所提到的,您每隔5分钟轮询一次并且从错误中看起来打开连接似乎很昂贵,请不要使用您的datacontext。

相反,在您拥有此方法的类中实现IDisposable,使您的datacontext成为类的私有成员并在Dispose()方法中,只需丢弃您的datacontext,这将依次释放数据库连接,当实例你的课程将超出范围。

此致 Kajal