10

ADO を介して MSSQL2000 サーバー上の単一のテーブルにアクセスする VB6 アプリケーションがあります。読み取り専用アクセス (adOpenStatic、adLockReadOnly) を使用しています ネットワークには、テーブルに変更を加える他のアプリケーションがあります。

なんらかの理由で、自分のアプリケーションがデッドロックの対象として選択されているというエラーが発生します。

私は本当に混乱しています: 1 つのテーブルから読み込んでいるときにデッドロックが発生するのはなぜですか? 他のアプリケーションの書き込みのためにタイムアウトが発生すると予想されますが、デッドロックではありません...

誰かがこれに光を当てることができますか?

UPDATE: 2009-06-15私はまだこの問題の解決策に興味があります。だから私はいくつかのより多くの情報を提供しています:

  • adOpenForwardOnly または adOpenStatic を選択しても違いはありません
  • カーソル位置がクライアントかサーバーかは関係ありません。
4

8 に答える 8

16

クラスター化されていないインデックスが存在するために、単一の SELECT ステートメントが単一の UPDATE または DELETE ステートメントに対してデッドロックする可能性があります。次のシナリオを検討してください。

リーダー (アプリ) は、最初に非クラスター化インデックスの共有ロックを取得してルックアップを実行し、次に、データ自体を返すためにデータを含むページの共有ロックを取得しようとします。

ライター (他のアプリ) は、最初にデータを含むデータベース ページで排他ロックを取得し、次にインデックスを更新するためにインデックスで排他ロックを取得しようとします。

この (およびその他の) 種類のデッドロックの詳細については、Microsoft KB 記事 Q169960 ( http://support.microsoft.com/kb/q169960/ )を参照してください。

また、デッドロック トレース情報 (トレース フラグ 1222) を取得する方法について Google で調べることもできます。これにより、デッドロックが発生するたびに、どの SQL ステートメントがどのオブジェクトに対して競合しているかが正確に報告されます。これはかなりまともな記事です - http://blogs.msdn.com/bartd/archive/2006/09/09/747119.aspx

于 2009-05-27T12:57:20.593 に答える
3

ここですでに提供されている回答には、いくつかの可能性があると思います。共有ロックのみを取得するため、デッドロックはロックのエスカレーションが原因ではなく、別のプロセスで取得したロックと互換性のないロックを取得し、それらのロックを別の順序で取得する必要があります...

共有ロックは、排他ロックを使用する別のプロセスと互換性がありません。シナリオは次のように実行される可能性があります...

  1. リソースAの共有ロックを取得します
  2. 他のプロセスはリソースBを排他的にロックします
  3. 他のプロセスは、リソースAの排他ロックを取得しようとし、Aの共有ロックを解放するのを待っているブロックをブロックします。
  4. リソースBの共有ロックを取得しようとすると、他のプロセスがBの排他ロックを解放するのを待つのをブロックします。ただし、サーバーによって識別され、強制終了するプロセスを選択するデッドロック状態になっている場合を除きます。 。

NBデッドロックには、2人よりも多くのプレーヤーがいる可能性があります。デッドロックを引き起こす一連の織り交ぜられたアクティビティが存在する場合もありますが、原則は同じです。

多くの場合、複数のアプリケーションが同じデータベースにアクセスする場合、ストアドプロシージャを介してすべてのアクセスを管理するDBAが存在するため、リソースが常に同じ順序でロックされていることを確認できます。そのような状況ではなく、他のアプリケーションがアドホックSQLステートメントを使用している場合は、コードを調べて、私が説明した方法でアプリと競合する可能性があるかどうかを確認する必要があります。それは面白そうに聞こえません。

実用的な解決策は、トランザクションがデッドロックの犠牲者として強制終了されたときにエラーをキャッチし、トランザクションを数回再試行することです。他のアプリが生成しているアクティビティの量によっては、この方法で許容できる結果が得られる場合があります。

于 2009-06-16T11:18:23.160 に答える
0

DB が非 atmic 読み取りの途中で書き込みが行われないようにするために、読み取りでは引き続きロックが発生する可能性があります。つまり、読み取りロックにより、選択しているデータの正確で一貫したスナップショットを取得できます。

于 2009-05-11T08:08:57.233 に答える
0

と同じ動作をしadOpenForwardOnlyますか?

SQL Server 統計が最新であることを確認することをお勧めします。または、DBA にすべてのインデックスを再構築してもらうこともできます。多くのロックの問題は、古い統計/インデックスが原因です。

于 2009-05-11T08:11:32.173 に答える
-1

両方のアプリケーションの動作に依存します。アプリがリソースを解放するのを確実に待つことができます。

于 2009-05-11T08:07:08.047 に答える
-1

デッドロックとは、2 つ以上のプロセスが相互にリソースを解放するのを待っている状態、または 3 つ以上のプロセスが循環チェーン内のリソースを待機している状態を指します。読み取りは待機しないため、読み取り専用アクセスでデッドロックを作成できます。

ウィキペディアにデッドロック状態についての素晴らしい説明があります

于 2009-05-11T08:09:49.680 に答える
-2

こんな感じではないでしょうか。

その他のアプリケーション: テーブルへの書き込み (テーブルへの書き込みロックの取得)

あなたのアプリケーション:テーブルから読み取ります(テーブルの読み取りロックを取得します。書き込みロックのためにできません)。

于 2009-05-11T08:03:36.040 に答える