MySQL 数据连接未关闭/池化
我正在开发完全重新开发的网站和销售系统,并且很快就遇到了这个 Max_connections 问题。
我发布了这个问题: 关闭/池化 MySQL ODBC 连接 最近,但此后尝试了其他一些事情,仍然一片空白,但可以提供更多细节...
我建立了一个相当复杂的销售流程,在创建发票时,我似乎留下了 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) 没有关闭连接(这个问题在我尝试手动关闭连接之前就出现了)
I am working on completely redeveloped website and sales system and have come up against this Max_connections issue surprisingly quickly.
I posted this question:
Closing/Pooling MySQL ODBC connections
Recently, but have since tried a few other things, still drawing a blank, but have more detail to offer...
I have a built a pretty complex sales process, and in creating an invoice I seem to be leaving 7 "processes" running each time. I have counted the number of times the data connection is used during the process of creating an invoice, and it is 7-9 depending on a few conditional values, so effectively the data connections are not closing at all.
To try to speed up coding, I have made a couple of functions which handle my database connectivity, so I will post these below.
Firstly, my connection string is:
"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"
The functions which I am using to open and close and do stuff with the database are as follows:
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
This function gives me a OdbcConnection Connection String Object, which I can then use with:
Function openDatabase(sql As String) As OdbcCommand
openDatabase = New OdbcCommand(sql, connectionString(sql, ""))
End Function
This function creates a useable data object when called doing something like:
Dim stockLevel As OdbcCommand = openDatabase("SQL STATEMENT HERE")
Dim objDataReader As OdbcDataReader = stockLevel.ExecuteReader(CommandBehavior.CloseConnection)
'=== DO STUFF WITH objDataReader ==='
objDataReader.Close()
Having read up trying to ensure data connections were closing properly and so on I read that adding (CommandBehavior.CloseConnection) should ensure that the connection is closed when no longer used, but this doesn't seem to be happening, so I have created a separate "closeCOnnection" function, which looks like:
Function closeConn()
If connectionString("", "", "close") IsNot Nothing AndAlso connectionString("", "close").State = ConnectionState.Open Then
connectionString("", "close").Close()
connectionString("", "close").Dispose()
End If
End Function
This is called after every use of the openDatabase function and also within the functions I have created for insert/update and delete, which look like this:
Function insertData(InsertSql As String)
Dim dataInsert = openDatabase(InsertSql, "new")
dataInsert.ExecuteNonQuery()
closeConn()
End Function
I am not sure whether making all these functions is making my life easier or harder, but I was trying to reduce the code in each file where data acceess is required, but I'm not convinced it has.
However, it has made it clear where and when I am opening and closing the database (or at least trying to)
The processes are not being closed though. If I run my sale process through 3 or 4 times in quick succession, with these 7 processes still being live and added to, I get the max_connections issue.
Not completely understanding how database connections work, I am afraid I am at a loss with this and hence having to ask you... again!!
Can anyone tell me:
a) Is my connection string correct, is there a better connection available for MySQL?
b) Using this method, creating a ODBCConnection Object, is it possible to close it within a function like this?
c) Why is (CommandBehavior.CloseConnection) not closing the connection (this problem arose before I tried closing the connection manually)
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(1)
不幸的是,您遇到的问题来自您的设计和对连接的引用处理不当。
但不用担心。修复起来并不困难。 :-)
在 VB.Net 中,您总是需要按照以下模式访问数据:
这有一些变体,例如在关闭连接之前循环行,但通常这就是它的工作方式。为了确保连接关闭,VB.Net提供了Try/Finally块和Using语句。您需要使用其中之一来确保连接已关闭。
我将通过以正确的方式重写您的方法来向您展示我的意思。
首先,将您的连接创建代码包装到一个函数中。
其次,编写一个函数来创建命令。 (openDatabase 是错误的名称,所以我将其更改为 CreateCommand)。
现在,当您希望在数据库中执行查询或语句时,可以遵循以下模式:
使用 Try/Finally 块意味着连接将始终正确关闭,即使异常导致代码在您期望之前返回到。
另一种简写是Using语句(它实际上与Finally块中的Dispose执行完全相同的操作):
如果您想将InsertData函数包装在命令中,您可以这样做:
我怀疑第一次你尝试过这个,你让你的连接保持打开状态,而没有关闭它们。我还假设(根据您所写的内容)您添加了 closeConn 方法来解决这个问题。不幸的是,每次调用
connectionString
时,您实际上都是在创建并打开一个新连接,然后您可以对其调用Close
或Dispose
。初始连接永远不会关闭。希望有帮助。
Unfortunately the issues you are having come from your design and a mishandling of references to connections.
But don't worry. It's not difficult to fix. :-)
In VB.Net you always need to access data in the following pattern:
There are variations of this, such as looping over rows before closing the connection, but generally this is how it works. In order to ensure that the connection is closed, VB.Net provides Try/Finally blocks and Using statements. You need to use one of these to make sure the connections are closed.
I'll show you what I mean by rewriting your methods in the proper manner.
Firstly, wrap your connection-creation code into a function.
Secondly, write a function to create your command. (openDatabase is the wrong name, so I have changed it to CreateCommand).
Now when you wish to execute a query or a statement in the database, you can follow this pattern:
Using the Try/Finally block means that the connection will always be closed correctly, even when an Exception causes the code to return before you expect it to.
An alternative shorthand is the Using statement (which effectively does exactly the same thing as the Dispose in a Finally block):
And if you want to wrap your InsertData function in a command, you can do it like this:
I suspect that the first time you tried this, you were leaving your connections open without ever closing them. I also assume (from what you wrote) that you added the closeConn method to sort that out. Unfortunately, every time you call
connectionString
you are actually creating and opening a new connection, which you then callClose
orDispose
on. The initial connection is never closed.Hope that helps.