質問編集履歴

1 説明文・コードを追加しました。

just

just score 82

2015/10/21 15:23  投稿

データベースをまたがったトランザクションについて
お世話になります。
現在、複数のデータベース定義を一度に変更するパッチをPHPで書いています。
たとえばtest1,test2,test3というデータベース(テーブル定義は同じ)があった場合、
ひとつずつデータベースに接続してSQLを実行して変更していくのですが、
test3で障害が発生したときtest1,test2の変更をロールバックしたいです。
test1,test2,test3はあくまで例で、データベースは顧客数分あります(顧客毎にDBを分ける設計)。  
当然、保存されているデータはデータベース毎に異なりますが、新機能追加にあたり、  
データベース定義が変更されることになりました。  
手動で変更をかけると人的ミスが起こりうるのでパッチを書くことになった、という経緯があります。  
 
調べたところ、データベースをまたがったトランザクションの例はなかなか
出てこないのですがPHPで実装可能でしょうか?
出てこないのですがPHPで実装可能でしょうか?
最初に書いたコードを記載します。
```PHP
   // 事前処理は省略
   // 更新用データベース名の格納された配列
   $corp_list;
   // トランザクション開始
   pg_query("BEGIN");
   // クエリ実行の成否
   $db_ret = 0;
   // 企業数   
   $cnt = 0;
   
   foreach ($corp_list as $key => $val) {
       echo "処理開始 => DB名:{$val} n";
       
       // PostgreSQLに接続
       $con = pg_connect("dbname=$val その他接続情報");
       if(!$con){
           $db_ret = 1;
           break;
       }
       
       // 更新用SQLの取得、実行
       $query = 更新用SQL;
       $result = pg_query($con, $query);
       if(!$result){
           echo "SQL実行ERRORn";
           $db_ret = 1;
           break;
       }   
     
       echo "処理終了 => OKn";
       // PostgreSQL接続クローズ
       pg_close($con);
       $cnt++;
   }
   // トランザクション終了 0:コミット、0以外:ロールバック
   if($db_ret == 0) {
       echo "COMMIT実行n";
       pg_query("COMMIT");
   }else {
       echo "ROLLBACK実行n";
       pg_query("ROLLBACK");
   }
   // DB切断
   $dbl->disconnect();
   echo "処理件数 => {$cnt} n";
```
これを実行すると、途中でエラーになってROLLBACKを実行しても変更済みのデータベースが
ロールバックされません。
ご意見・ご指摘いただけますでしょうか。
  • PHP

    24023 questions

    PHPは、Webサイト構築に特化して開発されたプログラミング言語です。大きな特徴のひとつは、HTMLに直接プログラムを埋め込むことができるという点です。PHPを用いることで、HTMLを動的コンテンツとして出力できます。HTMLがそのままブラウザに表示されるのに対し、PHPプログラムはサーバ側で実行された結果がブラウザに表示されるため、PHPスクリプトは「サーバサイドスクリプト」と呼ばれています。

  • PostgreSQL

    1354 questions

    PostgreSQLはオープンソースのオブジェクトリレーショナルデータベース管理システムです。 Oracle Databaseで使われるPL/SQLを参考に実装されたビルトイン言語で、Windows、 Mac、Linux、UNIX、MSなどいくつものプラットフォームに対応しています。

思考するエンジニアのためのQ&Aサイト「teratail」について詳しく知る