検索

広告

posted by fanblog

2015年10月23日

PostgreSQL×PHPの2相コミット


複数のDBにまたがって処理を行う際に、すべてのDBで整合性が保たれるようにするには、
2相コミット(2フェーズコミット)を用います。

postgresqlでは、「PREPARE TRANSACTION」を使用します。

PHPファイルで書きたかったので、pg_queryコマンドを用います。

以下、3つのDBにまたがって処理を行う場合の例です。
3つのDBに、同じ処理を行う場合を記載します。


//DBに接続
$db1 = pg_connect( "dbname=db1" );
$db2 = pg_connect( "dbname=db2" );
$db3 = pg_connect( "dbname=db3" );
//コネクションを配列に格納
$db_array = array("db1","db2","db3");

$ret = 0;

foreach($db_array as $key => $value){
//BEGINで開始する
pg_query( $db_array[$key], 'BEGIN' );

$result = pg_query( $db_array[$key], "SQL" );
// 失敗したら、フラグをたててループを抜ける
if(!$result){
$ret = 1;
break;
}
// PREPARE TRANSACTIONのあとは、ユニークなid。
pg_query( $db_array[$key], "PREPARE TRANSACTION '$db_array[$key]'" );
}
foreach($db_array as $key => $value){
if ( $ret = 0 ) {
//すべて成功したらコミット
pg_query( $db_array[$key], "COMMIT PREPARED '$db_array[$key]'" );
}
else {
//失敗があればロールバック
pg_query( $db_array[$key], "ROLLBACK PREPARED '$db_array[$key]'" );
}
}



ざっとコードを書いてしまいましたが、やり方としては

@biginメソッドでトランザクションを開始
Ainsert,update,delete等でデータベースに対する更新を実行
Bprepare transactionコマンドによって2相コミットを開始
ex)prepare transaction 'id_01';
C対象となるすべてのDBに対して@-Bを実行する
Dコミット/ロールバックを確定
・コミットの場合:commit preparedコマンド
ex) commit prepared 'id_01';
・ロールバックの場合:rollback preparedコマンド
ex) rollback prepared 'id_01';
E対象となるすべてのDBに対してDを実行する
※"prepared transaction"を発行されたDBに対しては、必ずcommit/rollback処理を行うようにすること。

以上で2相コミットの処理は終了となります。




posted by newprogramer at 23:35| Comment(0) | TrackBack(0) | DB
この記事へのコメント
コメントを書く

お名前:

メールアドレス:


ホームページアドレス:

コメント:

※ブログオーナーが承認したコメントのみ表示されます。

この記事へのトラックバックURL
http://fanblogs.jp/tb/4325060
※ブログオーナーが承認したトラックバックのみ表示されます。

この記事へのトラックバック
カテゴリーアーカイブ
最新記事
×

この広告は30日以上新しい記事の更新がないブログに表示されております。