sql >> データベース >  >> RDS >> Sqlserver

SQLServerのロックを使用してトランザクションの同時実行性を管理する

    マルチユーザー環境では、切り捨ての同時実行性を維持することが不可欠です。これらのロックは、サイズが96バイトのメモリ内構造です。それらの役割は、各トランザクションのデータの整合性、一貫性、同時実行制御を維持することです。 SQL Serverは、各トランザクションのACIDテストに従います。

    • A tomicity:このプロパティは、2つ以上のプロセスを含むトランザクションが完全にコミットされるか、どのプロセスもコミットされないことを保証します。
    • C 一貫性:コミットされたトランザクションの状態について保証します。トランザクションは、データの新しい状態を作成するか、既存の(トランザクションの前の)状態に戻る必要があります。
    • solation:トランザクションが互いに分離されていることを示します。トランザクションが実行されていて、データをコミットしなかった場合、他のトランザクションから分離されます。
    • D 耐久性:耐久性により、コミットされたデータが失われることはありません。電源やオペレーティングシステムの障害、またはその他のソフトウェアによるエラーを防ぎます。

    ACIDプロパティを確保するために、SQLServerはオブジェクトにさまざまな種類のロックを課します。この場合、他のトランザクションはロックが解除されるまで待機する必要があります。

    ロックモード

    SQL Serverは、トランザクションごとに次のロックモードを使用します。

    • 共有ロック:
      • このロックでは、SQL Serverにより、他のセッションがデータを読み取るために選択された操作を実行できるようになります。ただし、ロックがアクティブになるまで更新はできません。
      • 複数のトランザクションにより、行またはページに同時に共有ロックを課すことができます。
      • これは、データベースオブジェクトに表示される一般的なロックです。

    次のT-SQLでは、特定の顧客IDの顧客レコードを取得します。さらに、動的管理ビューsys.dm_tran_locksを使用して、既存のロックを確認します。

    BEGIN TRAN
    SELECT * FROM [SalesLT].[Customer] WITH (HOLDLOCK)
    WHERE CustomerID=1
        
    SELECT resource_type, request_mode, resource_description
    FROM   sys.dm_tran_locks
    WHERE  resource_type <> 'DATABASE'
    
    ROLLBACK
    

    以下に示すように、指定されたリソースID(8194443284a0)に共有ロックがあります:

    • 排他的(X)ロック:
      • SQL ServerはDML操作(削除、挿入、または更新)に排他ロック(X)を使用するため、行またはページのデータを変更する必要があります。
      • ロックが設定されるまで、他のユーザーがリソースにアクセスするのを防ぎます。
      • SQL Serverは、トランザクションのページまたは行に対して1つの排他ロックのみを持つことができます。

    この例では、顧客ID 1のレコードを更新する必要があります。したがって、SQLServerではリソースの排他ロックが必要です。トランザクションが完了するまで、他のトランザクションはこのリソースの排他ロックを取得できません。

    BEGIN TRAN
    UPDATE [SalesLT].[Customer] 
    SET Suffix='Mr.'  
    WHERE CustomerID=1
        
    SELECT resource_type, request_mode, resource_description
    FROM   sys.dm_tran_locks
    WHERE  resource_type <> 'DATABASE'
    
    ROLLBACK
    
    • 更新(U)ロック:
      • 更新ロックは排他ロックに似ています。共有ロックを持つレコードに配置できます。
      • 更新ロックは、特定の行に別の共有ロックを配置します。レコードを変更できるようになると、SQLServerは更新ロックを排他ロックに変換します。
      • SQL Serverは、更新ロックを使用してリソースに共有ロックを設定できません。
      • WITHUPDLOCKを使用して更新ロックを強制することもできます。

    次の例は、リソースID(8194443284a0)の更新ロックを示しています。

    BEGIN TRAN
    SELECT * FROM [SalesLT].[Customer] WITH (UPDLOCK)
    WHERE CustomerID=1
        
    SELECT resource_type, request_mode, resource_description
    FROM   sys.dm_tran_locks
    WHERE  resource_type <> 'DATABASE'
    
    ROLLBACK
    
    • インテントロック:
      • その目的は、ロックを取得する意図についてトランザクションに通知することです。これは、トランザクションで階層の下位にあるリソースの共有ロックまたは排他ロックが必要な場合に発生します。
      • このトランザクションでは、他のトランザクションがインテントロックを使用してテーブルの排他ロックを取得することはできません。
      • インテントロックの種類は次のとおりです。
        • 意図共有(IS)ロック:SQL Serverが、下位階層リソースで共有ロックを個別に取得することにより、下位階層リソースを読み取る意図を示します。
        • インテントエクスクルーシブ(IX)ロック:SQL Serverが、下位階層リソースの排他ロックを取得することにより、下位階層リソースを変更する意図を示します。
        • インテント更新ロック(IU):下位階層のリソースに対してのみページレベルで取得でき、更新が完了すると、IXロックに変換されます。

    以下に示すように、トランザクションにはキーに対する排他的ロックがあり、ページレベルにはインテント排他的ロックがあります。

    変換ロック

    SQL Serverは、トランザクションで複数のクエリをサポートするようにロックタイプを変換します。これらのロックは、変換ロックと呼ばれます。

    • 6 –インテント排他ロックと共有:SQL Serverトランザクションは、複数のページで共有ロックを保持し、排他を持っています 複数の行をロックします。
    • SIU – SQL Serverトランザクションは、複数のページで共有ロックを保持し、更新があります 複数の行をロックします。
    • UIX-インテント排他ロックを使用した更新:SQL Serverトランザクションは、複数のページで更新ロックを保持し、排他を持っています 複数の行をロックします。

    スキーマロック

    SQLServerは2種類のスキーマロックを取得します。

    • スキーマ安定性ロック(Sch-S):このロックは、スキーマに依存するクエリがコンパイルされ、その実行プランが生成されているときに使用されます。 Sch-Sロックは、オブジェクトデータへのアクセスをブロックしません。
    • スキーマ変更ロック(Sch-M):このロックは、DDL(データ定義言語)クエリの実行の結果です。 SQL Serverは、オブジェクトに対して1つのスキーマ変更ロックのみを持つことができます。このスキーマロックを使用してオブジェクトを変更することはできません。

    以下の例では、オブジェクト定義を変更しているときにSch-SロックとSch-Mロックの両方を取得します。

    BEGIN TRAN
    Alter TABLE DemoTable ADD new bit
    SELECT resource_type, request_mode, resource_description
    FROM   sys.dm_tran_locks
    WHERE  resource_type <> 'DATABASE'
    ROLLBACK

    ロックの互換性

    ロックの互換性は、同じリソースで同時に複数のトランザクションが発生した場合に、許可されたロックを確認するのに役立ちます。トランザクションがロックを設定する場合、別のトランザクションによって設定された新しいロックはそれと互換性がある必要があります。したがって、次のロック互換性リストを調べて、複数のトランザクション中にサポートされているロックを見つけることができます。

    ロックエスカレーション

    SQL Serverは、メモリ不足を引き起こす可能性のあるロックが多すぎるのを防ぐために、ロックエスカレーション機能を導入しました。 SQL Serverは、特定のスキャンで保持されているロックの数と、トランザクション全体およびメモリによって動的に保持されているロックの数を考慮します。 SQL Serverは、ロックエスカレーションで低レベルのロックを高レベルのロックに変換します。たとえば、行ロックをページレベルのロックに変換します。

    ロックのエスカレーションには次のしきい値を使用します。

    • メモリのしきい値: ロックメモリのしきい値は、ロックメモリの40%に設定されています。
    • ロックしきい値: 現在のテーブルまたはインデックスで取得されたロックの数が5000を超える場合、ロックのエスカレーションがトリガーされる可能性があります。

    ユーザーは、altertableステートメントを使用してロックのエスカレーションを制御できます。パラメータ値DISABLEを使用して、そのテーブルのロックエスカレーションを完全に無効にすることができます。

    ALTER TABLE Table_name SET (LOCK_ESCALATION = < TABLE | AUTO | DISABLE > –One of those options) GO

    Microsoftのドキュメントを参照できます ロックのエスカレーションを詳細に理解するため。

    注:より低い環境で徹底的にテストされるまで、ロックのエスカレーションを無効にしないでください。経験豊富なDBAのみが使用することをお勧めします。

    結論

    この記事では、ロックとそのエスカレーションプロセスを監視するためのSQLServerロックとDMVの詳細な概要を説明します。ロックはSQLServerのごく普通の動作であり、複数のトランザクションがどのように機能し、一貫性のあるデータをシミュレートして提供するかを理解するには、ロックに精通している必要があります。


    1. ユーザーストアドプロシージャの命名を避けるSP%またはSP_%

    2. smallint []列のGINインデックスが使用されていないか、エラー演算子が一意ではありません

    3. N番目に高い給与

    4. SQLServerで日付形式をDD/MMM/YYYY形式に変換する