あなたが説明した状況でデータの損失を防ぐ方法は本当にありません。SQL Server は、デッドロックを検出し、強制終了する犠牲者を自動的に選択するように設計されています (もちろん、DEADLOCK_PRIORITY
重要度の低いクエリを指定する場合を除きます)。これは、データの一貫性を確保するために、ロールバックが発生し、SQL Server がハウスキーピングを行う必要があることを意味します。あなたはそれを邪魔しています。データの損失を回避する方法はありません。
リソースを使用しようとする 2 つのクエリがあり、デッドロックが発生したとします。一定の時間が経過すると、SQL Server はこれを検出し、1 つのスレッドを強制終了することを決定します。SQL Server はACIDの原則に準拠しているため、クエリは自動的に停止されるだけでなく、ロールバックが開始されます。このクエリが多くの変更を行った場合、スレッドが停止する前に、SQL Server がログをスクロールしてすべての変更を元に戻す必要があることを意味します。これは、SQL Server がデッドロックを検出してからデッドロックが解決されるまでに、非常に長い時間がかかることを意味します。デッドロック状態の SPID を強制終了してプロセスを迅速化しようとする必要はありません。
これは、技術的な制限というよりも、組織的および運用上の制限です。あなたと SQL Server を使用している従業員は、クエリを開始した場合は終了しなければならないことに注意する必要があります。これは、クエリが完了したかどうか、エラーが発生してロールバックする必要があるかどうか、デッドロック シナリオで強制終了されるように選択されてロールバックする必要があるかどうかなど、すべてのクエリを終了する必要があることを意味します。これを知っているので、SPID は時間がかかっているため、またはデッドロックされているため、SPID を殺すことはできないという考え方で前進する必要があります。生産性の低下が原因で SPID を強制終了するよう関係者に迫られている場合は、問題のあるクエリを最後まで実行しなければならない理由と、介入するとどうなるか (生産データの損失) について教育します。「すべき」または「すべきではない」ではなく、ビジネスに対するリスクの観点から話します。利害関係者が納得せず、それでも SPID を殺すようなことを望んでいる場合は、経営陣にエスカレートして決定を下してもらいます。あなたが経営者である場合は、利害関係者があなたに何か危険なことをするように求めていることを明確に文書化し、その文書を準備しておいてください。私を信じてください、彼らは本番サーバーが一日中ダウンしている理由を尋ね、あなたはすべてのプレイヤーとその役割を明確に文書化できる必要があります.
また、サーバーを使用している従業員に、大きなトランザクションを小さなトランザクションに分割する方法、またはBEGIN
/を使用する方法について教育しますCOMMIT
。これにより、問題が発生してクエリをロールバックする必要がある場合、数日ではなく数分または数時間かかります。過去 2 年間で、私のオフィスではデータが爆発的に増加し、現在ではそれぞれ 10 億行を超えるテーブルがいくつかあります。学習期間は非常に苦痛でした。人々が大規模な更新を行ったり、非常に大規模なデータ セットを構築しようとしたり、エラーが発生したり、その後のロールバックが DAYS になったりしたため、何週間も生産性が低下していました。クエリを小さなバッチに分割するための標準的な操作手順を学習して実装した後、状況は改善されました。それでも、DBA が SPID を殺し始めたらどうなっていたかを考えるとぞっとします。
要するに、SPID を強制終了し続けると、データの損失を防ぐためにできることは何もないということです。クエリが完了するか、強制終了されてロールバックが完了するまで、SQL Server でクエリの管理を続行する必要があります。これらのクエリを手動で強制終了しようとすると、データが失われます。それを回避する方法はありません。
参考文献:
http://msdn.microsoft.com/en-us/library/aa480356.aspx
http://technet.microsoft.com/en-us/library/aa213030%28v=sql.80%29.aspx
https://www.simple-talk.com/sql/database-administration/handling-deadlocks-in-sql-server/