10個のテーブルを更新するSQLServerストアドプロシージャと、それらの10個のテーブルのうち1つだけを更新するSQLServerストアドプロシージャがあります。それぞれsp_updateAllとsp_updateSingleと呼びましょう。たとえば、sp_updateAllの擬似コードは次のとおりです。
Create Stored Procedure sp_updateAll
Begin
Begin TRAN
UPDATE TABLE1
SET COLUMN = ‘VALUE’
UPDATE TABLE2
SET COLUMN = ‘VALUE’
…
UPDATE TABLE6
SET COLUMN = ‘VALUE’
…
UPDATE TABLE10
SET COLUMN = ‘VALUE’
COMMIT TRAN
End
sp_UpdateSingleの擬似コードは次のとおりです。//これによりTable6が
更新されます。たとえば、実際には10個のテーブルのいずれかになります。
Create Stored Procedure sp_updateSingle
Begin
Begin TRAN
IF sp_UpdateAll is in progress, return an error.
UPDATE TABLE6
SET COLUMN = ‘VALUE’
COMMIT TRAN
END
sp_updateAllの実行が開始されると、sp_updateSingleがエラーで返されることを確認したいと思います。つまり、sp_UpdateAllの実行中は、個々のテーブルの更新を許可しないでください。分離レベル/ロックのヒントを使用してこれを実現する方法はありますか?分離レベルをSerializableに設定した場合でも、sp_UpdateSingleがsp_UpdateAllと一緒に実行される可能性があります。たとえば、両方のトランザクションが同時に実行される場合、次のシナリオが発生する可能性があります。
- Tran1はsp_UpdateAllの実行を開始します。Tran2はsp_UpdateSingleの実行を開始します。
- Tran1は、UPDATETABLE6に到達する前に切り替えられます。したがって、TABLE6はTran1によってロックされていません。
- Tran2が実行され、コミットされます。
- Tran1は実行を継続します
これは可能ですか?もしそうなら、このケースを回避するための良いアプローチは何でしょうか?Tran1が実行を開始したことを維持する追加のテーブル(InUseインジケーターのようなもの)を探しますか?次に、このテーブルはsp_UpdateAllで更新される最初のテーブルである必要があります。インジケーターを設定し、sp_UpdateAllが完了したらクリアします。sp_UpdateSIngleは、更新を実行する前にこのインジケーターをチェックします。そのようなシナリオでどのようなアプローチが良いかを教えてください。
よろしく
Vikas