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

Postgresql:トランザクションの準備

    はい、可能ですが、本当に必要ですか?

    これが実際には2つの別個のデータベースである必要があると判断する前に、よく考えてください。

    両方の接続を開いたままにして、2番目のコマンドが失敗した場合は、最初のコマンドをロールバックすることができます。

    準備されたトランザクションが本当に必要な場合は、読み続けてください。

    スキーマに関して-便宜上、データベース側でシーケンスジェネレーターとRETURNING句を使用します。

    CREATE TABLE tbl_album (
      id    serial PRIMARY KEY,
      name  varchar(128) UNIQUE,
      ...
    );
    CREATE TABLE tbl_user_album (
      id          serial PRIMARY KEY,
      album_id    bigint NOT NULL,
      ...
    );
    

    これを適切に機能させるには、外部の接着剤(分散トランザクションコーディネーター(?))が必要になります。

    秘訣は、 PREPARE TRANSACTION> COMMITの代わりに 。次に、両方のトランザクションが成功した後、 COMMITPREPARED<を使用します。 / code>

    PHPの概念実証は以下のとおりです。

    警告! このコードにはクリティカルがありません パート-それはエラー制御です。 $ db2のエラー キャッチしてROLLBACKPREPAREDする必要があります $ db1で実行する必要があります エラーをキャッチしない場合は、 $ db1のままにします。 本当に、本当に悪い、凍結されたトランザクションで。

    <?php
    $db1 = pg_connect( "dbname=db1" );
    $db2 = pg_connect( "dbname=db2" );
    $transid = uniqid();
    
    pg_query( $db1, 'BEGIN' );
    $result = pg_query( $db1, "INSERT INTO tbl_album(name) VALUES('Absolutely Free') RETURNING id" );
    $row = pg_fetch_row($result);
    $albumid = $row[0];
    pg_query( $db1, "PREPARE TRANSACTION '$transid'" );
    if ( pg_query( $db2, "INSERT INTO tbl_user_album(album_id) VALUES($albumid)" ) ) {
        pg_query( $db1, "COMMIT PREPARED '$transid'" );
    }
    else {
        pg_query( $db1, "ROLLBACK PREPARED '$transid'" );
    }
    ?>
    

    そしてもう一度-あなたがそれを使う前に考えなさい。アーウィンが提案することはもっと賢明かもしれません。

    ああ、もう1つ注意してください...このPostgreSQL機能を使用するには、 max_prepared_transactions 構成変数をゼロ以外の値に設定します。



    1. SQL Serverトランザクションログ—パート1

    2. フルテキストブール検索でC++という用語を取得するにはどうすればよいですか?

    3. OracleXEインスタンスのSIDを変更するにはどうすればよいですか。

    4. 大規模なクエリで必要なMagentoSQLクエリヘルプ