c# - 处理与 MySql 的连接丢失

标签 c# mysql

我想检测与 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 对象尚未更新,它不关心新的连接状态。

  1. 处理连接丢失异常的最佳方法是什么?
  2. 如何在连接恢复时刷新 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/

相关文章:

导入wordpress数据库时出现mySQL 1046错误

javascript - 从自定义数据库连接类返回的值是 'undefined' ,使用node.js和ES6

MySQL 默认程序

c# - 使用 VS 2015 代码分析器出错

c# - 使用 PdfWriter 和 iTextSharp 以及 SetFontAndSize 函数的斜体文本

c# - Unity 2D脚本摩擦方程

c# - WPF ControlTemplate 从父资源继承样式

c# - 对 CLR 施加内存限制

mysql - 从一个表中加入计数以从另一个表中选择 - mysql

php - 如何在选项选择 php 中运行查询