【问题标题】:MySQL connectionstate doesn't work as expectedMySQL 连接状态无法按预期工作
【发布时间】:2018-08-25 11:27:11
【问题描述】:

我有用 vb.net 编写的表单应用程序。它使用 MySqlClient:

Imports MySql.Data.MySqlClient

Public Class frmTest
Dim AConn As MySqlConnection
Dim errMsg as String = ""

Sub New()
    Try
        'Opens connection as forms open and keep it open
        If checkConn() = False Then Throw New Exception(ErrMsg)
    Catch ex As Exception
        MsgBox(ex.Message)
    End Try
End Sub

Private Function checkConn() As Boolean
    Try
        'if connection is not initiated then initiate
        If IsNothing(AConn) Then AConn = New MySqlConnection(ConnSTR)

        'if connectionstate is any other than "open", reconnect  
        If AConn.State <> ConnectionState.Open Then
            closeConn()
            AConn.Open()
        End If

        Return True
    Catch ex As Exception
        ErrMsg = ex.Message
        Return False
    End Try
End Function

Sub closeConn()
    Try
        AConn.Close()
    Catch ex As Exception

    End Try
End Sub

Private Sub Button2_Click(sender As Object, e As EventArgs) Handles 
            Button2.Click
    Try
        If checkConn() = False then Throw New Exception(errMsg)
        Dim cmdCheck As New MySqlCommand("show databases;", AConn)
        cmdCheck.ExecuteNonQuery()
    Catch ex as Exception
        MsgBox(ex.Message)
    End Try
End Sub
End Class

现在,当我打开表单时,它工作正常。连接打开,单击我得到结果。然后,我让表单空闲 10 分钟,然后再次单击 button2。 它通过“checkConn”没有错误,它说connectionstate是“open”,但是,当涉及到“cmdCheck.ExecuteNonQuery()”行时,异常抛出:“致命错误......”。问题是连接状态(在 checkConn() 中)报告 Connection.Open,虽然它不是(我在服务器上检查过 - 由于处于不活动状态而关闭)。 有没有更好的方法来检查连接状态?

【问题讨论】:

    标签: mysql vb.net mysqlconnection


    【解决方案1】:

    你不是我见过的第一个使用这种方法的人。不。这不好。只需在需要的地方创建和销毁连接对象即可。去掉 AConn 字段和 checkConn 方法,像这样:

    Private Sub Button2_Click(sender As Object, e As EventArgs) Handles Button2.Click
        Try
            Using AConn As New MySqlConnection(ConnSTR)
                Dim cmdCheck As New MySqlCommand("show databases;", AConn)
                AConn.Open()
                cmdCheck.ExecuteNonQuery()
            End Using
        Catch ex as Exception
            MsgBox(ex.Message)
        End Try
    End Sub
    

    有时使用字段来保存对 ADO.NET 对象的引用是个好主意。这不是那些时代之一。根据需要创建 ADO.NET 对象应该是默认设置。

    ADO.NET 连接对象存在于高层,而实际的数据库连接存在于较低层。 ADO.NET 连接专门用于在需要时创建、尽可能晚地打开并尽可能早地关闭。 ADO.NET 为您管理底层数据库连接。如果您有一个 ADO.NET 连接对象打开了 10 分钟而大部分时间没有数据通过它,那么您做错了。

    【讨论】:

    • 感谢您的及时答复。您的代码错过了“Finally aconn.close”,我已经尝试过了。这种方法的坏处是“connection.close”不一定会关闭服务器上的连接(对此有解释,提到了连接池,但这是另一个主题),因此您最终会在服务器上获得大量“IDLE”连接.
    • 可能这就是连接池的效果。这是您的客户端应用程序真正需要的功能。查看更多如何控制它dev.mysql.com/doc/connector-net/en/…
    • 我的代码根本不会错过连接上的Close 调用。因为连接对象是使用Using 语句创建的,所以它被隐式地放置在End Using 行。这隐含地关闭了连接。正如建议的那样,您应该阅读连接池。它的工作方式应该是第一次创建 ADO.NET 连接对象时,会打开一个低级数据库连接。具有相同连接字符串的后续 ADO.NET 连接使用相同的低级连接它会超时并在一段时间后关闭,如果需要,稍后会打开另一个。
    • 我对命令对象也使用了 Using...End Using 块。 (和读者,如果有的话)这是正确的@jmcilhinney?
    • @Mary,我肯定会为数据阅读器这样做,您也可以使用命令,但实际上没有任何意义。命令对象通过继承 Component 具有 Dispose 方法。如果您没有以这种身份使用它,即将它添加到设计器中的表单中,则实际上没有任何东西可以处理。它不会伤害,但也无济于事。
    猜你喜欢
    • 2016-11-28
    • 1970-01-01
    • 2021-05-12
    • 2016-02-18
    • 2016-12-24
    • 2011-10-27
    • 2015-06-17
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多