我想检测与 MySql 数据库的连接状态。我的数据库部署在与我的应用程序不同的服务器上,很可能会通过网络失去与它的连接。所以我必须考虑到这种情况。
这是我到目前为止尝试过的(一个简化的测试示例):
static string connectionString = "***";
public static MySqlConnection Connection;
static System.Timers.Timer _timer;
static void _timer_Elapsed(object sender, ElapsedEventArgs e)
{
try
{
if (Connection.State != System.Data.ConnectionState.Open)
Connection.Open();
// Call method to invoke MySqlCommand.ExecuteNonQuery
mysqlCommand.ExecuteNonQuery();
}
catch (MySqlException ex)
{
Console.WriteLine("SQL EXCEPTION: " + ex);
// Handle all type of database exceptions
switch(ex.Number)
{...}
}
catch (Exception ex)
{
Console.WriteLine("OTHER EXCEPTION: " + ex);
}
}
static void Main(string[] args)
{
Connection = new MySqlConnection(connectionString);
_timer = new System.Timers.Timer(3000);
_timer.Elapsed += new ElapsedEventHandler(_timer_Elapsed);
_timer.Enabled = true;
Console.ReadKey();
}
如果与 MySql 的连接丢失,我得到一个一般异常:
IOException : Unable to write data to the transport connection: An established connection was aborted by the software in your host machine.
我原以为 MySqlException
会被触发,但事实并非如此。
此外,如果恢复与 MySql 的连接,我仍然会收到 IOException
而不是执行查询。似乎 MySqlConnection
对象尚未更新,它不关心新的连接状态。
- 处理连接丢失异常的最佳方法是什么?
- 如何在连接恢复时刷新
MySqlConnection
?
注意:我无法为每个新查询实例化一个新的 MySqlConnection
对象,因为我试图更改的程序有一个Singleton 属于 MySqlConnection
类型,仅初始化一次。我知道这是一个糟糕的设计,但我现在不想更改此设计。我只想捕获连接丢失异常并尝试刷新 MySqlConnection
以继续正常工作。
最佳答案
如果您的 MySqlConnection
实例失去了与 MySQL 服务器的连接,您不能指望该实例的连接会自动恢复或以其他方式恢复。
您需要尝试重新连接 MySqlConnection
的新实例。失去连接的那个现在处于终止状态,不能被重新使用。
要做到这一点,我想你可以这样做
...
catch (MySqlException ex)
{
if (/*ex is a connection drop */) {
Connection?.Dispose();
Connection = new MySqlConnection(...);
Connection.ConnectionString = /* your connection string */;
Connection.Open();
}
else {
throw;
}
}
您是对的,您的设计存在缺陷。如果不进行测试,很难判断您的缺陷是否致命。
这些 Connection 实例不是线程安全的或者以任何方式可重入。如果您在计时器处理程序或线程中使用一个,您可以仅在该上下文中使用它。否则,如果在调用计时器或线程时它已经在使用中,事情就会变得危险。如果你幸运的话,你会得到一个异常(exception)。如果你不那么幸运,你的 MySQL 服务器将从你的客户端接收到乱码并检测到它。如果您的运气更差,您的数据将被打乱。
ADO.NET 和 MySqlConnection object implement connection pooling .这很重要,因为它使打开连接、使用它们然后关闭它们比您预期的要便宜得多。
有时 MySQL 会丢弃您的程序长时间保持打开的连接。如果这是您的问题,这篇文章可能会有所帮助。 How can I change the default Mysql connection timeout when connecting through python?
关于c# - 处理与 MySql 的连接丢失,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43454153/