2016-05-22 10 views
0

SQL Serverデータベースで作業を開始しましたが、Transaction Isolation Levelsを理解しようとするのは苦労しています。トランザクション中にデータがロックされる方法

私は次のような単純なタスクaccomlishしようとしています:IDは、特定のテーブルに存在するかどうかを判断するSQLストアドプロシージャ

    • [ID、カウンター]整数のペアを受け入れた:SELCT COUNT(*) FROM MyTable WHERE Id = {idParam}
    • 以前COUNTステートメントが0を返す場合、このIDとカウンターを挿入:COUNT文が1を返す場合 INSERT INTO MyTable(Id, Counter) VALUES({idParam}, {counterParam})
    • は、既存のレコードを更新:を(

    は今、私はトランザクションでこの全体のストアドプロシージャをラップする必要が理解し、そしてthis MS articleに応じて適切な分離レベルはSERIALIZABLEだろう、それは言う:他のトランザクションはによって読み取られたデータを変更することはできません現在のトランザクションが完了するまで)。私がここで間違っているなら、私を修正してください。

    ID = 1のプロシージャを呼び出すと、最初のクエリはSELCT COUNT(*) FROM MyTable WHERE SomeId=1(最初のトランザクションが開始された)になります。次に、このクエリが実行された直後に、ID = 2(2番目のトランザクションが開始された)でプロシージャが呼び出されます。これはその第一の意味は、

    • 第一トランザクションの第一クエリが0のレコードを返した場合:私は理解できないのは何

      は、この場合の私のストアド・プロシージャの実行中にロックされるだろうどのくらいのデータであり、トランザクションは何もロックせず、他のトランザクションは1回目のトランザクションがそれを試行する前にID = 1をINSERTできますか?

    • 2番目のトランザクションが同じ行の読み取り/更新を試みることは決してできませんが、最初のトランザクションはテーブル全体をロックしますか?
    • また、1番目のトランザクションでは、ID = 1のレコードのみを読み書きすることを禁じられていますか?
  • 答えて

    0

    フィルタがインデックス上にある場合、ロックされることになります。したがって、行がすでに存在するかどうかにかかわらず、トランザクションの間ロックされます。しかし、気をつけてください。行ロックをより厄介なもの、特に完全なテーブルロックにするのは非常に簡単です。もちろん、このようにデッドロックを導入するのは簡単です:)

    しかし、私は別のアプローチを提案します。まず、インサートをしようとします。それがうまくいけば、完了です。もしそうでなければ、原子的な更新を安全に行うことができます。非常に高速で、非常に安く、非常に信頼できる:)

    +0

    私はいつも同じIDでprocを呼び出し、重複するインデックスを挿入して、毎回挿入エラーを起こそうとします - これは本当に速くなるでしょうか? – holdenmcgrohen

    +0

    @holdenmcgrohenはい、非常に高速です。ユニークなインデックスチェック*は速くなければなりません。しかし、プロファイリングは常にあなたの友人です:)いずれにしても、私はOPのケースがクライアント - >サーバーI/Oによって完全に支配されると思います。 – Luaan

    関連する問題