1

私は完全に再開発された Web サイトと販売システムに取り組んでおり、この 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) が接続を閉じないのはなぜですか (この問題は、接続を手動で閉じようとする前に発生しました)

4

1 に答える 1

6

残念ながら、あなたが抱えている問題は、あなたの設計と接続への参照の誤った扱いに起因しています。

しかし、心配しないでください。修正するのは難しくありません。:-)

VB.Net では、常に次のパターンでデータにアクセスする必要があります。

  1. 接続を作成します。
  2. 接続を使用するコマンドを作成します (パラメーター値の追加を含む)。
  3. 接続を開きます。
  4. コマンドを実行します。
  5. 接続を閉じます。

これには、接続を閉じる前に行をループするなどのバリエーションがありますが、一般的にはこのように動作します。接続が確実に閉じられるようにするために、VB.Net はTry/Finally ブロック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 ブロックを使用するということは、例外によってコードが予想よりも早く返された場合でも、接続が常に正しく閉じられることを意味します。

別の省略形は Using ステートメントです (これは、Finally ブロックの 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。初期接続が閉じられることはありません。

それが役立つことを願っています。

于 2012-01-09T21:18:04.657 に答える