【サクッと解説】PHP トランザクション処理と例外対応

目次

1. 本記事のポイント

  • PHPのPDOによるトランザクション制御の基本を解説
  • try-catchを使った例外処理との組み合わせ方を紹介
  • 実務で重要なロールバックとコミットの設計判断にも触れる

2. PHPのトランザクション処理と例外対応とは?

トランザクション処理とは、複数のデータベース操作を「ひとまとまりの処理単位」として扱い、全体が成功したときだけ反映し、どれかが失敗した場合にはすべてを取り消す仕組みです。これにより、データの整合性を保つことができます。

PHPでは主にPDO(PHP Data Objects)を使ってトランザクションを扱います。トランザクション処理の開始、コミット、ロールバックを明示的に呼び出すことで制御できます。

実務では、トランザクションと例外処理を組み合わせて使うのが一般的です。データ更新中にエラーが起きた場合はロールバックし、正常時はコミットします。この一連の流れをtry-catchブロック内で処理することで、安全なエラーハンドリングが可能になります。

3. 詳細解説

典型的なトランザクションの使い方

データベース操作を複数実行し、途中で失敗した場合にすべてを取り消す例です。

PHP
<?php
$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'pass');
$pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);

try {
    // トランザクション開始
    $pdo->beginTransaction();

    // データの挿入処理
    $pdo->exec("INSERT INTO users (name) VALUES ('Taro')");
    $pdo->exec("INSERT INTO orders (user_id, amount) VALUES (LAST_INSERT_ID(), 1000)");

    // 正常に完了した場合はコミット
    $pdo->commit();
} catch (Exception $e) {
    // 例外発生時はロールバック
    $pdo->rollBack();
    echo "エラー: " . $e->getMessage();
}

このコードは、usersorders の両方のテーブルに対して処理を行い、どちらかが失敗するとすべてを元に戻します。

ロールバック忘れの例とその対策

例外が起きた際にロールバックをしないコードは、トランザクションが未完了のまま残ってしまい、意図しない動作を引き起こします。

PHP
try {
    $pdo->beginTransaction();
    // ... 何らかの操作
    throw new Exception("処理中にエラー発生");
    $pdo->commit();
} catch (Exception $e) {
    // ロールバックがない → 問題
    echo $e->getMessage();
}

改善点: catch内で必ず rollBack() を呼び出すこと。

明示的な再スローによる例外の伝播

上位層で例外処理を統一したい場合、catch後に例外を再スローすることで対応します。

PHP
try {
    $pdo->beginTransaction();
    // 複数のDB操作
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    throw $e; // 呼び出し元に再スロー
}

このパターンは、例外のログを別途管理したい場合や、呼び出し側で画面表示を制御したい場合に有効です。

4. よくあるミス・誤解・落とし穴

  • PDOのエラーモード設定を忘れると例外が発生しないPDO::ATTR_ERRMODEPDO::ERRMODE_EXCEPTION にしておかないと、失敗時に例外が発生せず false が返るだけになります。
  • ネストされたトランザクション:PDOはネイティブにネストトランザクションをサポートしていません。ネストの必要がある場合はアプリケーション側で工夫が必要です。
  • 例外を握りつぶしてしまう:catch内でエラーログだけ出力して throw しないと、呼び出し元では正常終了と認識されるため注意。
  • コミット忘れ:明示的に commit() を書かないと、トランザクションは確定されません。明示的な終了処理が必要です。

5. まとめ

PHPのトランザクション処理は、PDOとtry-catchを組み合わせることで安全に制御できます。重要なのは、処理成功時の commit() と失敗時の rollBack() を適切に配置し、例外発生時に確実にロールバックすることです。

また、PDOのエラーモード設定を忘れないこと、catch後の再スローによる例外伝播なども、実務では重要なポイントとなります。

よかったらシェアしてね!
  • URLをコピーしました!
目次