過去からの爆発... SQL 2005 サーバーに常駐するデータの管理に使用される老朽化した Access 2000 adp を管理する任務を負いました。データフォームの 1 つで、フィールドを変更してその変更をデータベースに保存しようとすると、約 1 分後にタイムアウトします。タイムアウト制限を増やしても、タイムアウト エラー メッセージの表示が遅くなるだけです。互換性を確保するために、通常のトラブルシューティングをすべて実行しました (たとえば、この SO の質問を参照してください)。
セットアップは次のとおりです。フォームはレコード セットにバインドされます (SELECT * FROM table_name
クエリとしてデータベースから読み取られます。結果セットのサイズは、フォームに設定されたフィルターによって異なりますが、通常、結果は約 200 レコードになります (それほど多くはありません)。データ...) フォームの一部のフィールドは、関連付けられたイベント ハンドラーで自動保存をトリガーします。これは次のようになります。
Private Sub EndDate_Exit(Cancel As Integer)
some checking goes here...
...
DoCmd.RunCommand acCmdSaveRecord
End Sub
コードが実行されるたびにDoCmd.RunCommand acCmdSaveRecord
、タイムアウト エラーが発生するまで ADP がフリーズします。もう少し掘り下げて、SQL Server のアクティビティ モニターを調べました。は、変更されたデータを保存するためにステートメントをサーバーに返しますacCmdSaveRecord
。UPDATE
ステートメント自体は、基になるテーブルの主キーに基づいて MS Access によって自動的に作成されますが、これは正しく定義されているようです。ただし、更新は、上記SELECT
のクエリに対応する実行中のステートメントによってブロックされます。SELECT * FROM table_name
これはデッドロックにつながります: ユーザーの変更により がトリガーされ、実行中UPDATE
の によってブロックされますSELECT
(これは、編集中のフォームから発生したように見えます)。どうすればこれを回避できますか?
私たちが試したこと:
- ステートメントを削除
DoCmd.RunCommand acCmdSaveRecord
し、コードに置き換えましたMe.Dirty = False
。これにより、上記とまったく同じ動作が発生します。 - 完全なものを削除し
acCmdSaveRecord
、組み込みの Access メニューを使用して変更を保存しました。これは #1 と同等の機能であり、まったく同じ動作になります。 acCmdSaveRecord
呼び出しを、特定のフィールドへの変更を保存するストアド プロシージャに置き換えます。GUI( を呼び出す保存ボタンacCmdSaveRecord
)からレコード全体を保存すると同じデッドロックが発生することを除いて、うまく機能します。- フォームに関連付けられた結果セットのサイズを数レコードに減らしました。奇妙なことに、まったく同じ動作を示します。