我的进程后台运行了一个更新线程,使用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;
}
答案 0 :(得分:0)
正如您所提到的,您每隔5分钟轮询一次并且从错误中看起来打开连接似乎很昂贵,请不要使用您的datacontext。
相反,在您拥有此方法的类中实现IDisposable,使您的datacontext成为类的私有成员并在Dispose()方法中,只需丢弃您的datacontext,这将依次释放数据库连接,当实例你的课程将超出范围。
此致 Kajal