我正在完全重新开发网站和销售系统,并且出人意料地很快就遇到了这个 Max_connections 问题。
我发布了这个问题: Closing/Pooling MySQL ODBC connections 最近,但此后尝试了一些其他的东西,仍然是空白,但有更多细节可以提供...
我建立了一个相当复杂的销售流程,在创建发票时,我似乎每次都要运行 7 个“流程”。我计算了在创建发票的过程中使用数据连接的次数,根据一些条件值,它是 7-9 次,因此实际上数据连接根本没有关闭。
为了尝试加快编码速度,我制作了几个处理数据库连接的函数,因此我将在下面发布它们。
首先,我的连接字符串是:
"DRIVER={MySQL ODBC 3.51 Driver}; SERVER=mysql.dc-servers.com; DATABASE=jamieha_admin; UID=USERID; PASSWORD=pWD; OPTION=3;pooled=true;Max Pool Size=100"
我用来打开和关闭数据库以及对数据库进行操作的函数如下:
Function connectionString(sql As String, closeConnection As String) As OdbcConnection
Dim DBConnection As String = ConfigurationManager.ConnectionStrings("dbConnNew").ConnectionString
'this is getting the connection string from web.config file.
Dim oConnection As OdbcConnection = New OdbcConnection(DBConnection) 'call data connection
connectionString = New OdbcConnection(DBConnection)
If closeConnection <> "close" Then _
connectionString.Open() ' open data connection
End Function
此函数为我提供了一个 OdbcConnection 连接字符串对象,然后我可以将其用于:
Function openDatabase(sql As String) As OdbcCommand
openDatabase = New OdbcCommand(sql, connectionString(sql, ""))
End Function
此函数在调用时创建一个可用的数据对象,如下所示:
Dim stockLevel As OdbcCommand = openDatabase("SQL STATEMENT HERE")
Dim objDataReader As OdbcDataReader = stockLevel.ExecuteReader(CommandBehavior.CloseConnection)
'=== DO STUFF WITH objDataReader ==='
objDataReader.Close()
读完试图确保数据连接正确关闭等等我读到添加(CommandBehavior.CloseConnection)应该确保连接在不再使用时关闭,但这似乎没有发生,所以我已经创建了一个单独的“closeCOnnection”函数,它看起来像:
Function closeConn()
If connectionString("", "", "close") IsNot Nothing AndAlso connectionString("", "close").State = ConnectionState.Open Then
connectionString("", "close").Close()
connectionString("", "close").Dispose()
End If
End Function
这在每次使用 openDatabase 函数后调用,也在我为插入/更新和删除创建的函数中调用,如下所示:
Function insertData(InsertSql As String)
Dim dataInsert = openDatabase(InsertSql, "new")
dataInsert.ExecuteNonQuery()
closeConn()
End Function
我不确定制作所有这些功能是否让我的生活更轻松或更艰难,但我试图减少每个需要数据访问的文件中的代码,但我不相信它确实如此。
但是,它已经明确了我打开和关闭数据库的位置和时间(或者至少试图)
虽然进程没有被关闭。如果我快速连续运行我的销售流程 3 或 4 次,而这 7 个流程仍在运行并添加到其中,我就会遇到 max_connections 问题。
没有完全理解数据库连接是如何工作的,恐怕我对此一头雾水,因此不得不再次问你......!
谁能告诉我:
a) 我的连接字符串是否正确,是否有更好的 MySQL 可用连接?
b) 使用这个方法,创建一个 ODBCConnection 对象,是否可以在这样的函数中关闭它?
c) 为什么 (CommandBehavior.CloseConnection) 没有关闭连接(这个问题出现在我尝试手动关闭连接之前)
最佳答案
不幸的是,您遇到的问题来自您的设计和对连接的引用处理不当。
但别担心。修复起来并不难。 :-)
在 VB.Net 中,您总是需要以下列模式访问数据:
- 创建连接。
- 创建一个使用连接的命令(包括添加任何参数值)。
- 打开连接。
- 执行命令。
- 关闭连接。
这有一些变体,例如在关闭连接之前循环遍历行,但通常这就是它的工作方式。为了确保关闭连接,VB.Net 提供了Try/Finally block 和Using 语句。您需要使用其中之一来确保连接已关闭。
我将通过以正确的方式重写您的方法来向您展示我的意思。
首先,将您的连接创建代码包装到一个函数中。
Function GetConnection() As OdbcConnection
Dim DBConnection As String = ConfigurationManager.ConnectionStrings("dbConnNew").ConnectionString
GetConnection = New OdbcConnection(DBConnection)
End Function
其次,编写一个函数来创建您的命令。 (openDatabase 是错误的名称,所以我将其更改为 CreateCommand)。
Function CreateCommand(sql As String, connection As OdbcConnection) As OdbcCommand
CreateCommand = New OdbcCommand(sql, connection)
End Function
现在,当您希望在数据库中执行查询或语句时,可以遵循以下模式:
Dim connection As OdbcConnection = GetConnection()
Dim stockLevel As OdbcCommand = CreateCommand("SQL STATEMENT HERE", connection)
Try
connection.Open()
Dim objDataReader As OdbcDataReader = stockLevel.ExecuteReader(CommandBehavior.CloseConnection)
Finally
connection.Dispose()
End Try
使用 Try/Finally block 意味着连接将始终正确关闭,即使异常导致代码在您预期之前返回也是如此。
另一种简写形式是 Using 语句(它的作用与 Finally block 中的 Dispose 完全相同):
Dim connection As OdbcConnection = GetConnection()
Dim stockLevel As OdbcCommand = CreateCommand("SQL STATEMENT HERE", connection)
Using connection
connection.Open()
Dim objDataReader As OdbcDataReader = stockLevel.ExecuteReader(CommandBehavior.CloseConnection)
End Using
如果您想将 InsertData 函数包装在一个命令中,您可以这样做:
Dim connection As OdbcConnection = GetConnection()
Dim stockLevel As OdbcCommand = CreateCommand(InsertSql, connection)
Using connection
connection.Open()
Dim result As Integer = stockLevel.ExecuteNonQuery()
End Using
我怀疑您第一次尝试此操作时,没有关闭连接就让连接保持打开状态。我还假设(从你写的)你添加了 closeConn 方法来解决这个问题。不幸的是,每次您调用 connectionString
时,您实际上是在创建并打开一个新连接,然后您在该连接上调用 Close
或 Dispose
。初始连接永远不会关闭。
希望对您有所帮助。
关于MySQL DataConnections 未关闭/合并,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/8792472/