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

一括更新および削除操作を実行する際のPostgreSQLデッドロックの回避

    順序付けられたサブクエリで明示的な行レベルのロックを使用する 競合するすべてのクエリで
    SELECT 書き込みロックと競合しません。)

    DELETE

    DELETE FROM table_name t
    USING (
       SELECT id_A, id_B
       FROM   table_name 
       WHERE  id_A = ANY(array_of_id_A)
       AND    id_B = ANY(array_of_id_B)
       ORDER  BY id_A, id_B
       FOR    UPDATE
       ) del
    WHERE  t.id_A = del.id_A
    AND    t.id_B = del.id_B;
    

    UPDATE

    UPDATE table_name t
    SET    val_1 = 'some value'
         , val_2 = 'some value'
    FROM  (
       SELECT id_A, id_B
       FROM   table_name 
       WHERE  id_A = ANY(array_of_id_A)
       AND    id_B = ANY(array_of_id_B)
       ORDER  BY id_A, id_B
       FOR    NO KEY UPDATE  -- Postgres 9.3+
    -- FOR    UPDATE         -- for older versions or updates on key columns
       ) upd
    WHERE  t.id_A = upd.id_A
    AND    t.id_B = upd.id_B;
    

    このようにして、マニュアルでアドバイスされているように、行は一貫した順序でロックされます。

    id_Aと仮定します 、id_B 更新されることはなく、マニュアルの「注意」ボックスに詳述されているようなまれなコーナーケースの複雑化もあり得ません。

    キー列を更新していない間は、弱いロックモードを使用できますFOR NO KEY UPDATE 。 Postgres9.3以降が必要です。

    もう1つ(遅い そして確かに)オプションは、競合するトランザクションにシリアル化可能な分離レベルを使用することです。シリアル化の失敗に備える必要があります。その場合、コマンドを再試行する必要があります。




    1. Androidコンテンツプロバイダーに見つからないコンテンツプロバイダーのURLを修正するにはどうすればよいですか?

    2. Ubuntu20.04にClickHouseをインストールして構成する方法

    3. MySQLSELECTはnull値ではない

    4. データベースのセキュリティ-転送中および保存中のバックアップ暗号化