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

SQL ServerでDEADLOCKをシミュレートする方法は?

    以下に示す手順を使用して、デッドロックを作成できます。まず、サンプルデータを使用してグローバル一時テーブルを作成します。

    --Two global temp tables with sample data for demo purposes.
    CREATE TABLE ##Employees (
        EmpId INT IDENTITY,
        EmpName VARCHAR(16),
        Phone VARCHAR(16)
    )
    GO
    
    INSERT INTO ##Employees (EmpName, Phone)
    VALUES ('Martha', '800-555-1212'), ('Jimmy', '619-555-8080')
    GO
    
    CREATE TABLE ##Suppliers(
        SupplierId INT IDENTITY,
        SupplierName VARCHAR(64),
        Fax VARCHAR(16)
    )
    GO
    
    INSERT INTO ##Suppliers (SupplierName, Fax)
    VALUES ('Acme', '877-555-6060'), ('Rockwell', '800-257-1234')
    GO
    

    次に、SSMSで2つの空のクエリウィンドウを開きます。セッション1のコードを一方のクエリウィンドウに配置し、セッション2のコードをもう一方のクエリウィンドウに配置します。次に、必要に応じて2つのクエリウィンドウ間を行き来しながら、2つのセッションのそれぞれを段階的に実行します。各トランザクションには、他のトランザクションもロックを要求しているリソースのロックがあることに注意してください。

    Session 1                   | Session 2
    ===========================================================
    BEGIN TRAN;                 | BEGIN TRAN;
    ===========================================================
    UPDATE ##Employees
    SET EmpName = 'Mary'
    WHERE EmpId = 1
    ===========================================================
                                 | UPDATE ##Suppliers
                                 | SET Fax = N'555-1212'
                                 | WHERE SupplierId = 1
    ===========================================================
    UPDATE ##Suppliers
    SET Fax = N'555-1212'
    WHERE SupplierId = 1
    ===========================================================
    <blocked>                    | UPDATE ##Employees
                                 | SET Phone = N'555-9999'
                                 | WHERE EmpId = 1
    ===========================================================
                                 | <blocked>
    ===========================================================
    

    デッドロックが発生します。 1つのトランザクションが終了し、もう1つのトランザクションが中止され、エラーメッセージ1205がクライアントに送信されます。

    「セッション1」と「セッション2」のSSMSクエリウィンドウを閉じて、開いているトランザクションをコミット(またはロールバック)します。最後に、一時テーブルをクリーンアップします:

    DROP TABLE ##Employees
    GO
    DROP TABLE ##Suppliers
    GO
    



    1. CodeIgniterget_whereを使用して'および'および'または'ステートメントをチェーンします

    2. 同じ数値データ型への2つの外部キーと、それを2つのテーブルへの参照

    3. Spring Boot / JPA / mySQL-多対1の関係では、SQLクエリが多すぎます

    4. 複数の列を1つの列に変換するOracleクエリ