PostgreSQL×PHPの2相コミット

DB

複数の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メソッドでトランザクションを開始
②insert,update,delete等でデータベースに対する更新を実行
③prepare transactionコマンドによって2相コミットを開始
ex)prepare transaction ‘id_01’;
④対象となるすべてのDBに対して①-③を実行する
⑤コミット/ロールバックを確定
・コミットの場合:commit preparedコマンド
ex) commit prepared ‘id_01’;
・ロールバックの場合:rollback preparedコマンド
ex) rollback prepared ‘id_01’;
⑥対象となるすべてのDBに対して⑤を実行する
※”prepared transaction”を発行されたDBに対しては、必ずcommit/rollback処理を行うようにすること。
以上で2相コミットの処理は終了となります。


タイトルとURLをコピーしました