2017-04-17 84 views
1

我想检测连接状态到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异常:无法写入数据传输到传输连接: 建立的连接被主机 机器中的软件中止。

我期待MySqlException被解雇,但事实并非如此。 此外,如果与MySql的连接恢复,我仍然可以获得IOException而不是执行查询。似乎,MySqlConnection对象尚未更新,它不关心新的连接状态。

  1. 什么是处理连接丢失异常的最佳方法?
  2. 如何在连接恢复时刷新MySqlConnection

注:,我不能实例为每个新查询的新MySqlConnection对象,因为我想改变程序具有只初始化一次MySqlConnection类型的辛格尔顿。我知道这是一个糟糕的设计,但我现在不想改变这种设计。我只想抓住连接丢失的异常并尝试刷新MySqlConnection以继续正常工作。

回答

0

如果您的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; 
    } 
    } 

你是正确的,你的设计有缺陷。没有测试,你的缺陷是否是致命的是很难说的。

这些连接实例是非线程安全或以任何方式重入。如果在定时器处理程序或线程中使用一个,则可能只有在该上下文中使用它。否则,如果在您的计时器或线程被调用时它已经在使用中,事情会变得非常危险。如果你幸运的话,你会得到一个例外。如果你不那么幸运,你的MySQL服务器会收到客户端的乱码并检测到它。如果你不那么幸运,你的数据会被炒得沸沸扬扬。

ADO.NET和MySqlConnection object implement connection pooling。这很重要,因为它会打开连接,使用它们,然后关闭它们,比您预期的便宜很多。

有时MySQL会丢失程序长时间处于打开状态的连接。如果这是你的问题,这篇文章可能会有帮助。 How can I change the default Mysql connection timeout when connecting through python?

+0

所以我唯一的选择是改变我的设计,并为每个数据库交互创建新的MySqlConnection实例? – Mhd