我想检测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:无法将数据写入传输连接:An 建立的连接被主机中的软件中止 机。
我期待MySqlException
被解雇但事实并非如此。
此外,如果恢复与MySql的连接,我仍然得到IOException
而不是执行查询。好像,MySqlConnection
对象尚未更新,并且它并不关心新的连接状态。
MySqlConnection
? 注意:我无法为每个新查询实例化一个新的MySqlConnection
对象,因为我尝试更改的程序有一个 Singleton 1>}类型,只初始化一次。我知道这是一个糟糕的设计,但我现在不想改变这个设计。我只想捕获连接丢失的异常并尝试刷新MySqlConnection
以继续正常工作。
答案 0 :(得分: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?
答案 1 :(得分:0)
当您由于网络问题而失去连接时,连接对象不会更改Status属性,因此请在执行命令之前无法对其进行评估。 但是,数据库属性(connection.database)变为空字符串,因此您可以对其进行评估,以便可以关闭连接并恢复它:
oConn is an instance of MySQLConnection (it works on odbcconnection)
[VB.NET]
If Not IsNothing(oConn) Then
If (oConn.Database.Equals(String.Empty)) Then oConn.Close()
End If
[C#]
If (Not IsNothing(oConn)){
If (oConn.Database.Equals(String.Empty)) oConn.Close();
}