2

このデータのいくつかの集計を事前に計算するために、テーブル内のデータが変更された後に実行されるコストのかかるストアドプロシージャがあります。(SPは、関連する場合、テーブルのトリガーではなくアプリケーションによって呼び出されますが、これは難しい要件ではありません)。ストアドプロシージャは、ほぼ完全にINSERT INTO ... SELECTステートメントです。

データは通常、頻繁に変更されません(つまり、SPの呼び出しは頻繁ではありません)が、原則として重複する可能性があります。この場合の一貫性を確保するsp_getapplockために、2番目の呼び出しが最初の呼び出しが完了するのを待ってから続行するように使用します。

これは機能しますが、待機は非効率的で不要です。ストアドプロシージャが最初に行うことは、既存の(現在は古くなっている)データをすべて削除することです。私が本当に望んでいるのは、2回目の呼び出しで、最初の呼び出しに「あなたがしていることをわざわざ続けないでください。状況が変わったので、実行を停止して、正しい状態のままにしておきます」と伝えることです。

この場合、2番目の呼び出しで最初のSP呼び出しを確実に中止するための確実な方法はありますか?

4

2 に答える 2

3

変更のたびに再集計する必要は本当にありますか?

後続の更新を進行中の更新に延期するだけで十分でしょうか?

中断できたとしても、トランザクションがロールバックされるのを待つ必要があり、トランザクションが完了するのを待つよりも時間がかかる可能性があります。

于 2012-07-24T21:00:07.287 に答える
2

それを優雅に行う方法はありません。1 つのステートメントに対して「kill」を発行すると、そのステートメントの接続を不明な状態のままにすることができます。また、@GilM が (+1) を正しく指摘しているように、実行のフェーズによっては、ロールバックに完了よりも時間がかかる場合があります。

そこで、思いも寄らない提案をします。インデックス付きビューの使用について考えたことはありますか? これらは標準版で使用できますが、WITH (NOEXPAND)ヒントを使用してクエリを実行し、メリットを享受する必要があります。ただし、そのビューをヒントを含む別のビューにラップするだけです。

そうすれば、プロセス全体をいくつかの非常に良い利点に置き換えることができる場合があります。

  • 完全に透過的に更新されます。
  • 「セット全体を再集計」するよりもはるかに効率的です。
于 2012-07-24T21:06:24.023 に答える