0

データベースを別のサーバーに移動した後、複数の SELECT を実行すると、タイムアウトの問題に直面しています。パッチを適用する任務を負っていた遺物 (VB6 アプリケーション) です。古い環境では問題なく動作しましたが、新しい環境には古いテーブルのカーボンコピーが含まれています。

ノート!新しいデータベースはゼロから構築されました(つまり、DBA は多くの CREATE TABLE + INSERT スクリプトを実行してテーブルのカーボン コピーを作成し、それらに古いデータを入力しました)。

これはエラーソースです:

// "conn" is being initialized outside the function
Public Function PerformOperation(ByRef conn as ADODB.Connection, query as string) as Boolean
  Dim rs as ADODB.Recordset
  //This below is the timeout source
  rs.Open conn, query, adOpenStatic, adLockReadOnly

  If Not (rs.EOF or rs.BOF) Then
    rs.MoveFirst
    //assign data to many variables
  End If

ExitPoint:
  If Not (rs Is Nothing) Then
    If (rs.State = adStateOpen) Then rs.Close
    Set rs = Nothing
  End If   

  Exit Function

Error:
  MsgBox "Blah blah"
  Resume ExitPoint
  Resume 0

End Function

関数はこのように呼び出されます

conn = New ADODB.Connection
conn.ConnectionString = "..."
conn.Open

For i = 1 To RowCount //reading data from a grid component (data is correct!)
  //very long select here... kept short
  query = "SELECT something FROM somewhere WHERE <manyFields> = <manyValues>" 
  If PerformOperation(conn, query) = True Then
    //UPDATE another table based on the SELECT data
    // NOTE: this occurs on a DIFFERENT, INDEPENDENT ADODB.Connection object
  End If
Next i

1回目PerformOperationは問題なく呼び出され、2回目は設定に関係なくタイムアウトしCommandTimeoutます。サイクルが1回「循環」する場合も問題なく動作します。

ここでの大きな問題は、試してみる必要があるのは実稼働環境だけなので、特に注意する必要があることです。また、DBA に関する深い知識も手元にありません...非常に古いソフトウェアであり、最終的に .NET に移植される予定ですが、その間に対処する必要があります...

この問題を確認または修正するにはどうすればよいですか? これFor、サイクルのどの長さでも機能する必要があります

提案に感謝します(いつものように、重要な詳細を見逃した場合は指摘してください。できれば提供します)。

編集 #1 何が起こっているかについての詳細を提供するために、最初と 2 番目のコード ブロックを拡張しました。強調表示を修正するためにコメントが変更されました (単一引用符は色付けを台無しにします)。

編集 #2 接続文字列で複数のアクティブな結果セット (MARS) を有効にしても、どちらも役に立ちませんでした。

4

2 に答える 2

1

これまでうまく機能してきたことに少し驚いています。

開いているレコードセットを閉じる必要があります。そうしないと、実行するクエリごとに 1 つのデータベース接続を使い果たしてしまいます。データベースはしばらくすると未使用の接続を再利用しますが、あまりにも多くの接続を急速に使い切ると、ユーザーごとの接続数の制限に達し、データベースはそれ以上の接続を拒否します。

古いデータベースでまったく機能した理由は、おそらく、必要に応じて新しい接続を作成したためです。これは後のバージョンで変更されており、設定を変更して、よりリソースを浪費する古い動作を許可する必要があります。ただし、その設定を変更することは、問題の良い解決策ではありません。

レコードセットが不要になったら、レコードセットを閉じて参照を削除します。これにより、接続が解放され、別のクエリに使用できるようになります。

Public Function PerformOperation(ByRef conn as ADODB.Connection, query as string) as Boolean
  Dim rs as ADODB.Recordset
  'This below is the timeout source
  rs.Open conn, query, adOpenStatic, adLockReadOnly

  rs.Close()
  Set rs = Nothing

  ' [cut]: PerformOperation returns true if SELECT returns something
End Function

編集:

以外adStateOpenにも開いている状態があります。おそらく、代わりに閉じた状態を確認する必要があります。

If (rs.State <> adStateClosed) Then rs.Close
于 2012-04-23T08:57:52.507 に答える
0

この行を編集して問題を解決しました:

If PerformOperation(conn, query) = True Then

このような

If PerformOperation(connOther, query) = True Then

基本的に、メソッド呼び出しは独自の接続に移動され、他の接続とまったく同じように宣言されています。現在は機能していますが、その理由はよくわかりません。これは、パッチを当てようとして乱暴に編集した結果です。

于 2012-06-06T12:34:48.297 に答える