はい、可能ですが、本当に必要ですか?
これが実際には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
構成変数をゼロ以外の値に設定します。