データベース PostgreSQL トランザクション

トランザクション

  • BEGIN

  • COMMIT

  • ROLLBACK

  • SAVEPOINT

    トランザクションでROLLBACK文ではとトランザクション全体が取り消されたが、セーブポイント機能を使って一部だけ実行を取りけり、トランザクションを継続することができる。
    SAVEPOINTは、PostgreSQL 8.0から加わった機能。

    SAVEPOINT savepoint_name
    ROLLBACK [TO SAVEPOINT savepoint_name]
    RELEASE [SAVEPOINT] savepoint_name




    モードと隔離レベル

    トランザクションには、モードと隔離レベルという2つの属性がある。

    モード
  • READ ONLY

  • READ WRITE

  • 隔離レベル
  • READ UNCOMMITTED

  • READ COMMITTED

  • REPEATABLE READ

  • SERIALIZABLE
  • これらは、トランザクション開始時に指定可能。
    BEGIN文のオプション、BEGIN直後のSET TRANSACTION文で設定できる。
    指定しなかった場合は、default_transaction_read_only, default_transaction_isolationの設定が適用される。


    インストール後の既定値はモードは「READ WRITE」、隔離レベルは、「READ COMMITTED」が設定されている。


    同時実行制御

    トランザクション隔離レベル

    標準SQLでは、トランザクション隔離レベルを3つの「望ましくない現象」がおきるかどうかによって定義している。


  • トランザクションの望ましくない現象

  • ダーティーリード同時に実行されている別のトランザクションが書き込んで、今COMMITしていないデータを読み込んでしまう
    反復不能読み取りトランザクションが反復して同じデータを読み込むとき、別のトランザクションがそのデータを更新してCOMMITしたために、同じデータを読んでいるにも関わらず、異なる結果を得てしまう。
    ファントムリードトランザクションがある検索条件で問い合わせを再実行したときに、別のトランザクションが書き込みをしてCOMMITしたために、同じ検索条件で問い合わせを実行したにも関わらず異なる結果を得てしまう。



    トランザクション隔離レベル

    隔離レベルダーティーリード反復不能読み取りファントムリード
    READ UNCOMMITTED起きる起きる起きる
    READ COMMITTED起きない起きる起きる
    REPEATABLE READ起きない起きない起きる
    起きない起きない起きない起きない

    PostgreSQLでは、READ COMMITTEDレベルとSERIALIZABLEレベルをサポートしている。

    PostgreSQLでは、トランザクション隔離レベルをSERIALIZABLEにした場合、同一トランザクション中に同じレコードを同時に更新すると、どちらかのトランザクションがエラーになり、ロールバックする。アプリケーション側では、そのシリアライゼーション失敗のエラーに対して再度実行する仕組みを作る必要がある。




    ロック

    PostgreSQLでは、トランザクション内で行の更新を行うと、レコードロックがかかる。更新を終了するまで、他のトランザクションによるそのレコードの更新は待たされる。

    DELETEやUPDATEなどの操作は伴わず、レコードロックだけをかけるには「SELECT 〜 FOR UPDATE」を使う。末尾にFOR UPDATE句をつけたSELECT文を実行すると、選択されたレコードにレコードロックがかかる。
    レコードロックを使う方式は、ブロックされることはあっても、トランザクション失敗時のやり直しをアプリケーション側で実装する必要がなくなる。

    SELECT * 
    FROM MYTABLE
    <B>FOR UPDATE</B>;

    テーブルロック

    LOCK [TABLE] table_name [IN lock_mode MODE] [NOWAIT]

    table_nameテーブル名
    lock_modeロックモード

    NOWAITロックが取得でないとき、待たずにエラーを返す

  • テーブルのロックモード

  • ロックモード取得する主なSQL競合するモード
    ACCESS SHARESELECT, ANALYZE
    ROW SHARESELECT FOR UPDATE
    ROW EXCLUSIVEUPDATE, DELETE, INSERT
    SHARE UPDATE EXCLUSIVEVACCUM
    SHARECREATE INDEX
    SHARE ROW EXCLUSIVELOCK文のみ
    EXCLUSIVELOCK文のみ
    ACCESS EXCLUSIVEVACUUM FULL, ALTER TABLE, DROP TABLE, REINDEX, CLUSTER