【发布时间】:2018-06-10 11:12:33
【问题描述】:
我正在开发一个连接到 SQL Server 的 C# 应用程序。如果网络连接中断,应用程序应该能够进入“只读模式”(离线模式)并且只能从本地数据库中读取数据。现在,我正在尝试弄清楚如何检测断开连接:
public int executeNonQuery(string query, List<SqlParameter> parameters)
{
int result;
using (SqlConnection sqlConnection = new SqlConnection(ConnectionString))
{
tryOpenSqlConnection(sqlConnection);
using (SqlCommand cmd = new SqlCommand(query, sqlConnection))
{
if (parameters != null)
{
cmd.Parameters.AddRange(parameters.ToArray());
}
result = cmd.ExecuteNonQuery();
}
sqlConnection.Close();
}
return result;
}
private void tryOpenSqlConnection(SqlConnection sqlConnection)
{
try
{
sqlConnection.Open();
}
catch (SqlException se)
{
if (se.Number == 26)
{
catchOfflineMode(se);
}
throw se;
}
}
//...
private void catchOfflineMode(SqlException se)
{
Console.WriteLine("SqlException: " + se.Message);
Console.WriteLine("Setting offline mode...");
//...
}
我想过使用 SQL 错误代码来检测连接丢失。但问题是,有时我只有在 SqlConnection 已经建立之后才会出现异常,例如在命令执行期间。我得到的最后一个例外是
错误代码 121 - 信号量超时期限已过
所以,我必须检查每一个可能与丢失网络连接有关的错误代码。
编辑:我还考虑捕获每个SqlException,然后检查以太网连接(例如 ping 服务器)以检查异常是否来自丢失的连接。
有更好的方法吗?
【问题讨论】:
-
检查每个请求的异常会导致性能问题。在Dependency Injection in .NET, section 9.2 书中描述了一种断路器模式,它专门用于支持“离线模式”,它比在每个请求上检查异常更实用。
-
在
SqlException的备注部分末尾:So, in general, write an exception handler that catches any provider specific exceptions as well as exceptions from the common language runtime.,然后进一步查看Number代表什么,你会发现this,这意味着你只是触及了表面你必须照顾的东西。 -
谢谢 NightOwl888,我去看看!
-
嗨 rene,我知道有很多错误需要考虑。这就是为什么我要问是否有更好的方法来处理它。捕捉每一个异常/错误对我来说似乎并不是最好的方法。但是如何从 sql 查询/连接中捕获异常,然后检查与服务器的连接呢?如果应用程序已经离线,我们不需要关心失败率。同时,我们确保每个操作都被考虑(通过在每次发生异常后检查连接)。
-
NightOwl888,我查看了断路器模式并使用了来自here 的简单实现正如您所说,断路器模式通过跟踪一段时间内的故障数量来解决性能问题,但是它不能解决如何检测网络连接断开的问题。此外,我需要立即对失败做出反应(如果一个数据库调用中断)。
标签: c# sql .net exception-handling offline-mode