4

環境

SQL Native Client 9.0 を使用して SQL Server 2000 データベースと通信する C++ アプリケーションに取り組んでいます。

シナリオ

  • 2 つの接続が DBMS に対して開かれています
  • 各接続はトランザクションを使用するように設定されています
  • Connection1で動作するクエリTableA
  • Connection2で動作するクエリTableB
  • TableBkey_idのフィールドに外部キー制約がありますTableA

次のことを行う関数を作成しました。

begin a transaction on Connection1 & Connection2
prepare a query in TableA on Connection1
prepare a query on TableB on Connection2

begin loop over some_data
   (1) insert into key_id on TableA

   begin loop over some_other_data
      (2) insert into TableB using same key_id as in Table A
   end loop
end loop

commit on Connection1
commit on Connection2

私が遭遇したのは、 query(1)が正常に実行されるということでしたが、 query に対して SQLExecute が呼び出されるとすぐ(2)に、デバッガーはネバーランドでオフになります。

質問

デッドロックの問題として何が起こっているかを正しく診断していますか?

1Connectionはキーを作成しているTableAがコミットしていないため、Connection2それに情報を追加しようとしてTableBいるため、外部キーの制約により、 にキーが存在する必要があることがわかりましたTableA。このため、SQLExecuteクエリはブロックされ、トランザクションが完了するのを待ちます。これは、コードの記述方法のおかげで、書き込みが完了するTableAまで実行できません。TableB

その他の注意事項

この問題を回避するためにコードを作成することはできますが、問題についての私の理解が正しいことを確認したいと思います。

4

1 に答える 1

7

TableA に対する TableB の外部キー制約は、キーの存在を確認するためにチェックする必要があります。次に、TableB レコードを受け入れるか拒否します。

キーを含む TableA レコードは (別の接続で) まだコミットされていないため、Foreign Key 制約は待機する必要があります。挿入は、TableA レコードがコミットまたはロールバックされるまで返されません。

最初の接続でのコミットは TableB の挿入が戻るのを待つため、デッドロックが発生します。

言い換えれば、あなたは正しいです。

于 2008-11-20T16:16:30.193 に答える