1. 本記事のポイント
- PHPのPDOによるトランザクション制御の基本を解説
- try-catchを使った例外処理との組み合わせ方を紹介
- 実務で重要なロールバックとコミットの設計判断にも触れる
2. PHPのトランザクション処理と例外対応とは?
トランザクション処理とは、複数のデータベース操作を「ひとまとまりの処理単位」として扱い、全体が成功したときだけ反映し、どれかが失敗した場合にはすべてを取り消す仕組みです。これにより、データの整合性を保つことができます。
PHPでは主にPDO(PHP Data Objects)を使ってトランザクションを扱います。トランザクション処理の開始、コミット、ロールバックを明示的に呼び出すことで制御できます。
実務では、トランザクションと例外処理を組み合わせて使うのが一般的です。データ更新中にエラーが起きた場合はロールバックし、正常時はコミットします。この一連の流れをtry-catchブロック内で処理することで、安全なエラーハンドリングが可能になります。
3. 詳細解説
典型的なトランザクションの使い方
データベース操作を複数実行し、途中で失敗した場合にすべてを取り消す例です。
<?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();
}
このコードは、users
と orders
の両方のテーブルに対して処理を行い、どちらかが失敗するとすべてを元に戻します。
ロールバック忘れの例とその対策
例外が起きた際にロールバックをしないコードは、トランザクションが未完了のまま残ってしまい、意図しない動作を引き起こします。
try {
$pdo->beginTransaction();
// ... 何らかの操作
throw new Exception("処理中にエラー発生");
$pdo->commit();
} catch (Exception $e) {
// ロールバックがない → 問題
echo $e->getMessage();
}
改善点: catch内で必ず rollBack()
を呼び出すこと。
明示的な再スローによる例外の伝播
上位層で例外処理を統一したい場合、catch後に例外を再スローすることで対応します。
try {
$pdo->beginTransaction();
// 複数のDB操作
$pdo->commit();
} catch (Exception $e) {
$pdo->rollBack();
throw $e; // 呼び出し元に再スロー
}
このパターンは、例外のログを別途管理したい場合や、呼び出し側で画面表示を制御したい場合に有効です。
4. よくあるミス・誤解・落とし穴
- PDOのエラーモード設定を忘れると例外が発生しない:
PDO::ATTR_ERRMODE
をPDO::ERRMODE_EXCEPTION
にしておかないと、失敗時に例外が発生せずfalse
が返るだけになります。 - ネストされたトランザクション:PDOはネイティブにネストトランザクションをサポートしていません。ネストの必要がある場合はアプリケーション側で工夫が必要です。
- 例外を握りつぶしてしまう:catch内でエラーログだけ出力して
throw
しないと、呼び出し元では正常終了と認識されるため注意。 - コミット忘れ:明示的に
commit()
を書かないと、トランザクションは確定されません。明示的な終了処理が必要です。
5. まとめ
PHPのトランザクション処理は、PDOとtry-catchを組み合わせることで安全に制御できます。重要なのは、処理成功時の commit()
と失敗時の rollBack()
を適切に配置し、例外発生時に確実にロールバックすることです。
また、PDOのエラーモード設定を忘れないこと、catch後の再スローによる例外伝播なども、実務では重要なポイントとなります。