【问题标题】:handling connection timeouts with Linq to SQL使用 Linq to SQL 处理连接超时
【发布时间】:2014-07-02 11:27:48
【问题描述】:

我有一个更新线程在我的进程后台运行,使用 Linq-to-SQL,它每 5 分钟查询一次 MS SQL Server 2008 R2 DB 以查找要更新的记录。定期我会看到一个异常:

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;
}

【问题讨论】:

    标签: c# sql sql-server linq


    【解决方案1】:

    正如您所提到的,您每 5 分钟进行一次轮询,并且从错误来看,打开连接似乎很昂贵,请勿与您的数据上下文一起使用。

    相反,在您拥有此方法的类中实现 IDisposable,使您的数据上下文成为类的私有成员,并在 Dispose() 方法中,只需处理掉您的数据上下文,这将反过来释放数据库连接以及当实例您的课程将超出范围。

    问候 卡哈尔

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-02-16
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2012-10-24
      相关资源
      最近更新 更多