質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

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

Q&A

解決済

2回答

2849閲覧

【PHP】catchブロック内でのロールバック失敗時の例外処理

退会済みユーザー

退会済みユーザー

総合スコア0

PDO

PDO(PHP Data Objects)はPHPのデータベース抽象化レイヤーです。

PHP

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

0グッド

1クリップ

投稿2018/02/21 22:29

DB書き込み時に、良く以下のような例外処理を目にしますが、このcatchブロック内でのrollBackに失敗した場合、その例外をキャッチできないと思うのですがその認識でよろしいでしょうか?

PHP

1try { 2 $dbh->beginTransaction(); 3 $dbh->exec("insert into user (id, name) values (1, 'Hoge')"); 4 $dbh->commit(); 5} catch (Exception $e) { 6 $dbh->rollBack(); //←ここで失敗した場合 7}

もし、上記でrollBackの例外をキャッチできない場合、キャッチするようにするためには、以下のような例外処理を書く必要があるのでしょうか?
http://php.net/manual/ja/pdo.rollback.php#75431

アプリケーションで例外をうまくハンドリングするためのあるべき姿を知りたいです。

よろしくお願いいたします。

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

yambejp

2018/02/22 00:33

コミットが失敗した上でロールバックが失敗するという状況について具体的な事例があれば挙げて下さい
退会済みユーザー

退会済みユーザー

2018/02/22 05:00 編集

すみません具体的な事例はありません。ただ質問のコードですと、コミットが失敗するとcatchブロック内に入り必ずrollBackも実行されるので、「コミットが失敗した上でロールバックが失敗するという状況」はあり得る話かと思います。
guest

回答2

0

ベストアンサー

メソッド名からするとPDOのようですが、PDOのrollBackで例外が発生するのは、有効なトランザクションがない場合だけです(PHPマニュアル)。つまり、今回のように確実にトランザクションを開いている場合には、データベースエンジンがトランザクション未対応だった場合や、他のトランザクションの中だったなどでトランザクションに入ること自体に失敗した場合を除けば、ロールバックが失敗することはありません。

回線が途切れた場合は、データベースサーバの側で自動的にロールバックしていきます。

投稿2018/02/21 23:25

maisumakun

総合スコア145183

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/02/22 05:19

> PDOのrollBackで例外が発生するのは、有効なトランザクションがない場合 その状況はPDOのcommitと同じですよね。なので冒頭の > catchブロック内でのrollBackに失敗した場合、その例外をキャッチできないと思うのですがその認識でよろしいでしょうか? に対するアンサーはYesですね? commitとrollBackで同じ「有効なトランザクションがない」例外が起こるということは commitで例外が発生した場合、catchブロックでの例外をキャッチしているのに、rollBackでも同じ例外が発生してそれを取り逃す可能性があり得ると思うのですが。 > 回線が途切れた場合は、データベースサーバの側で自動的にロールバック そのようなイレギュラーなケースはDBサーバーが良しなにやってくれるので、アプリ側では質問文のような例外処理で十分ということでしょうか?
maisumakun

2018/02/22 05:51

beginTransactionをtryから外せば、トランザクションが有効な場合のみcatchでrollbackする、という流れにできます(beginTransactionだけ別にtry-catchして、そちらはrollbackせずに終了させればいいですし)。
退会済みユーザー

退会済みユーザー

2018/02/22 23:52

なるほど。そういう方法もあるのですね。参考にさせていただきます!
guest

0

「コミットが失敗した上でロールバックが失敗するという状況」はあり得る

コミットが失敗したらコミットされないのだからロールバックは
できればやっておいてできなければヤラなければいいような気がしますけどね
実行していないんだからロールバックもなにもないような・・・
もちろんSQLのエラーについてはなんらかの形でcatchして
例外処理をいれたりログを残したりするのは賢明だと思います。

  • テストデータ

SQL

1create table tbl(id int unique,val int); 2insert into tbl values(1,100),(2,200),(3,300);
  • 例1

SQL

1start transaction; 2update tbl set val=val+1 where id=1; 3commit;

※成功:id=1のvalが100→101

  • 例2

SQL

1start transaction; 2update tbl set val=val+1 where id=2; 3rollback;

※成功:ただしロールバックしているのでid=2のvalは200のまま

SQL3

1start transaction; 2update tbl set val=val+1 where id=3; 3insert into tbl values(3,399); 4commit;

※失敗:本来問題ないid=3のval=300→301も取り消される

SQL

1start transaction; 2update tbl set val=val+1 where id=3; 3insert into tbl values(4,400); 4commit;

※成功:id=3のval=300→301、id=4の400も追加される

投稿2018/02/22 05:16

yambejp

総合スコア114784

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

退会済みユーザー

退会済みユーザー

2018/02/22 23:52

回答ありがとうございます!
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問