2

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と一緒に実行される可能性があります。たとえば、両方のトランザクションが同時に実行される場合、次のシナリオが発生する可能性があります。

  1. Tran1はsp_UpdateAllの実行を開始します。Tran2はsp_UpdateSingleの実行を開始します。
  2. Tran1は、UPDATETABLE6に到達する前に切り替えられます。したがって、TABLE6はTran1によってロックされていません。
  3. Tran2が実行され、コミットされます。
  4. Tran1は実行を継続します

これは可能ですか?もしそうなら、このケースを回避するための良いアプローチは何でしょうか?Tran1が実行を開始したことを維持する追加のテーブル(InUseインジケーターのようなもの)を探しますか?次に、このテーブルはsp_UpdateAllで更新される最初のテーブルである必要があります。インジケーターを設定し、sp_UpdateAllが完了したらクリアします。sp_UpdateSIngleは、更新を実行する前にこのインジケーターをチェックします。そのようなシナリオでどのようなアプローチが良いかを教えてください。

よろしく
Vikas

4

1 に答える 1