【PHP8.x】PDO::commit()メソッドの使い方
commitメソッドの使い方について、初心者にもわかりやすく解説します。
基本的な使い方
commitメソッドは、PDOクラスに属し、データベースのトランザクションにおける変更を確定・永続化するメソッドです。
このメソッドは、PDO::beginTransaction()で開始された一連の操作が全て成功した場合に呼び出し、変更をデータベースに適用します。トランザクションとは、複数のデータベース処理をひとまとまりとして扱い、全てが成功した場合に限り変更を反映し、失敗した場合は全てを取り消し(ロールバックし)元の状態に戻す仕組みです。commitメソッドが正常に実行されると、トランザクション内の変更を確定し、永続的に保存し、データの整合性と信頼性を保ちます。メソッドは成功するとtrue、失敗するとfalseを返します。変更を取り消す場合は、PDO::rollBack()メソッドを使用します。
構文(syntax)
1<?php 2$pdo = new PDO('mysql:host=localhost;dbname=testdb', 'user', 'password'); 3$pdo->commit(); 4?>
引数(parameters)
引数なし
引数はありません
戻り値(return)
bool
トランザクションのコミットが成功した場合は true を、失敗した場合は false を返します。
サンプルコード
PHP PDOトランザクションのcommitとrollback
1<?php 2 3/** 4 * PDO::commit() メソッドを使用してデータベーストランザクションを管理するサンプルコードです。 5 * 6 * この関数は、複数のデータベース操作を単一の論理的な作業単位として扱い、 7 * 全ての操作が成功した場合にコミット(変更を永続化)するか、 8 * 途中で失敗した場合にロールバック(変更を取り消し)する方法を示します。 9 * SQLiteのインメモリデータベースを使用するため、特別な設定なしで実行可能です。 10 */ 11function demonstratePdoTransaction(): void 12{ 13 // データベース接続設定 (SQLite インメモリデータベースを使用) 14 // 実際のアプリケーションでは、ここにデータベースの接続情報 (例: 'mysql:host=localhost;dbname=testdb', 'user', 'password') を設定します。 15 $dsn = 'sqlite::memory:'; 16 $username = null; // SQLiteインメモリでは不要 17 $password = null; // SQLiteインメモリでは不要 18 19 // PDO オプション: 20 // ATTR_ERRMODE => ERRMODE_EXCEPTION: エラー発生時にPDOExceptionをスローする設定。 21 // ATTR_DEFAULT_FETCH_MODE => FETCH_ASSOC: SELECT結果を連想配列で取得する設定。 22 $options = [ 23 PDO::ATTR_ERRMODE => PDO::ERRMODE_EXCEPTION, 24 PDO::ATTR_DEFAULT_FETCH_MODE => PDO::FETCH_ASSOC, 25 ]; 26 27 $pdo = null; // PDOオブジェクトを初期化 28 29 try { 30 // 1. データベース接続の確立 31 $pdo = new PDO($dsn, $username, $password, $options); 32 echo "データベース接続に成功しました。\n"; 33 34 // 2. テスト用のテーブルを作成 35 $pdo->exec("CREATE TABLE IF NOT EXISTS accounts ( 36 id INTEGER PRIMARY KEY AUTOINCREMENT, 37 user_name TEXT NOT NULL, 38 balance REAL NOT NULL 39 )"); 40 echo "accountsテーブルを作成または確認しました。\n"; 41 42 // 既存のデータをクリアして、毎回同じ初期状態から開始 43 $pdo->exec("DELETE FROM accounts"); 44 $pdo->exec("INSERT INTO accounts (user_name, balance) VALUES ('Alice', 100.00)"); 45 $pdo->exec("INSERT INTO accounts (user_name, balance) VALUES ('Bob', 50.00)"); 46 echo "初期データ (Alice: 100.00, Bob: 50.00) を挿入しました。\n"; 47 48 // 3. トランザクションを開始 49 // 以降の全てのデータベース操作は、commit() が呼び出されるまで一時的な状態となります。 50 $pdo->beginTransaction(); 51 echo "\nトランザクションを開始しました。\n"; 52 53 // 送金処理をシミュレート 54 $fromAccount = 'Alice'; 55 $toAccount = 'Bob'; 56 $amount = 30.00; 57 58 // 4. 送金元から金額を減算 59 $stmt = $pdo->prepare("UPDATE accounts SET balance = balance - ? WHERE user_name = ?"); 60 $stmt->execute([$amount, $fromAccount]); 61 echo "{$fromAccount} から {$amount} を減算しました。\n"; 62 63 // 意図的なエラーをシミュレートするフラグ (trueにするとロールバックされる) 64 $simulateFailure = false; 65 if ($simulateFailure) { 66 // エラーが発生した場合、catchブロックに制御が移り、ロールバックが実行されます。 67 throw new Exception("送金処理中に予期せぬエラーが発生しました。"); 68 } 69 70 // 5. 送金先に金額を加算 71 $stmt = $pdo->prepare("UPDATE accounts SET balance = balance + ? WHERE user_name = ?"); 72 $stmt->execute([$amount, $toAccount]); 73 echo "{$toAccount} に {$amount} を加算しました。\n"; 74 75 // 6. 全ての操作が成功した場合、変更をデータベースに永続的に保存(コミット) 76 // commit() が呼び出された時点で、上記 INSERT/UPDATE 操作が確定します。 77 $pdo->commit(); 78 echo "\nトランザクションをコミットしました。\n"; 79 echo "送金処理が正常に完了しました。\n"; 80 81 } catch (PDOException $e) { 82 // PDO関連のエラーが発生した場合 83 echo "\nデータベースエラーが発生しました: " . $e->getMessage() . "\n"; 84 // トランザクションがアクティブな場合のみロールバック 85 if ($pdo && $pdo->inTransaction()) { 86 $pdo->rollBack(); 87 echo "トランザクションをロールバックしました。変更は破棄されました。\n"; 88 } 89 } catch (Exception $e) { 90 // その他の一般エラーが発生した場合 91 echo "\n一般エラーが発生しました: " . $e->getMessage() . "\n"; 92 // トランザクションがアクティブな場合のみロールバック 93 if ($pdo && $pdo->inTransaction()) { 94 $pdo->rollBack(); 95 echo "トランザクションをロールバックしました。変更は破棄されました。\n"; 96 } 97 } finally { 98 // 処理後のデータベース状態を確認 99 echo "\n現在の口座残高:\n"; 100 if ($pdo) { 101 $stmt = $pdo->query("SELECT user_name, balance FROM accounts"); 102 $accounts = $stmt->fetchAll(); 103 foreach ($accounts as $account) { 104 echo "{$account['user_name']}: {$account['balance']}円\n"; 105 } 106 } else { 107 echo "データベースに接続できませんでした。\n"; 108 } 109 110 // データベース接続を閉じる (PDOオブジェクトがnullになると接続は閉じられます) 111 $pdo = null; 112 echo "\nデータベース接続を閉じました。\n"; 113 } 114} 115 116// 関数を実行 117demonstratePdoTransaction(); 118 119?>
このサンプルコードは、PHPのPDO::commit()メソッドを用いてデータベーストランザクションを管理する方法を示しています。PDO::commit()は、PDO::beginTransaction()で開始された一連のデータベース操作を最終的に確定させ、それまでの変更をデータベースに永続的に保存する役割を担います。このメソッドは引数を取りません。戻り値はbool型で、コミットが成功すればtrue、失敗すればfalseを返しますが、通常PDO::ATTR_ERRMODEがPDO::ERRMODE_EXCEPTIONに設定されている場合、コミット失敗時には例外がスローされるため、戻り値の直接的な確認はあまり行われません。
トランザクションは、複数のデータベース操作を一つのまとまりとして扱い、データの一貫性を保つために不可欠です。例えば、送金処理のように、ある口座から金額を減らし、別の口座に金額を増やすという二つの操作が全て成功した場合にのみ、全体を完了(コミット)させる必要があります。もし、これらの操作の途中でエラーが発生した際には、PDO::rollBack()メソッドが呼び出され、beginTransaction()以降に行われた全ての変更がキャンセルされ、データベースはトランザクション開始前の状態に戻ります。これにより、データが整合性のない状態で残ることを防ぎます。このサンプルコードでは、SQLiteのインメモリデータベースを利用し、送金処理の成功と、エラー発生時のロールバックの挙動を具体的に示しています。
PDO::commit()は、beginTransaction()で開始したデータベーストランザクション内の全ての変更を確定し、永続化するメソッドです。複数のデータベース操作を一つの論理的な作業単位として扱い、全ての操作が成功した場合にのみcommit()を呼び出して変更を保存することが極めて重要です。途中でエラーが発生した場合は、必ずロールバック(PDO::rollBack())を呼び出して、それまでの全ての変更を取り消してください。これにより、データベースのデータ整合性が確実に保たれます。rollBack()を実行する際は、トランザクションがアクティブであるか(PDO::inTransaction())をチェックすると、より安全に処理できます。実際のシステムでは、データベース接続情報やエラー処理をさらに堅牢に実装してください。
PHP PDO::commitでトランザクションを確定する
1<?php 2 3/** 4 * データベーストランザクションをコミットするサンプルコード。 5 * 6 * この関数は、PDO::commit メソッドの使用方法を示します。 7 * 複数のデータベース操作(例: データの挿入や更新)を一つの単位として扱い、 8 * 全ての操作が成功した場合のみ、その変更をデータベースに永続的に保存(コミット)します。 9 * 途中でエラーが発生した場合は、トランザクション開始以降の全ての変更を取り消し(ロールバック)ます。 10 * 11 * システムエンジニアを目指す初心者の方にも理解しやすいよう、 12 * 単体で動作可能なSQLiteのインメモリデータベースを使用しています。 13 * 14 * @return void 15 */ 16function demonstratePdoCommitTransaction(): void 17{ 18 $pdo = null; // PDOオブジェクトを初期化 19 20 try { 21 // 1. データベース接続の確立 22 // 'sqlite::memory:' を指定することで、ファイルではなくメモリ上に一時的なデータベースを作成します。 23 // これにより、追加のデータベース設定なしでコードをすぐに実行できます。 24 $pdo = new PDO('sqlite::memory:'); 25 26 // エラーモードを例外に設定: 27 // これにより、PDO関連の操作でエラーが発生した場合、PDOException がスローされるようになります。 28 // これを捕捉することで、エラー処理を容易に行うことができます。 29 $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); 30 31 echo "データベースに接続しました。\n"; 32 33 // 2. テーブルの作成 34 // データの挿入先となる 'users' テーブルを準備します。 35 // IF NOT EXISTS は、テーブルが既に存在する場合は作成しないようにします。 36 $pdo->exec("CREATE TABLE IF NOT EXISTS users ( 37 id INTEGER PRIMARY KEY AUTOINCREMENT, 38 name TEXT NOT NULL 39 )"); 40 echo "users テーブルを作成しました。\n"; 41 42 // 3. トランザクションの開始 43 // ここから 'commit()' または 'rollBack()' が呼び出されるまでの全てのデータベース操作は、 44 // 一つの論理的な作業単位として扱われます。 45 $pdo->beginTransaction(); 46 echo "トランザクションを開始しました。\n"; 47 48 // 4. データベース操作の実行 49 // 準備したINSERT文を使って、複数のユーザーデータを挿入します。 50 // これらはまだ一時的な変更であり、データベースには永続化されていません。 51 $stmt = $pdo->prepare("INSERT INTO users (name) VALUES (?)"); 52 $stmt->execute(['Alice']); 53 echo "ユーザー 'Alice' を挿入しました。\n"; 54 $stmt->execute(['Bob']); 55 echo "ユーザー 'Bob' を挿入しました。\n"; 56 57 // 意図的にエラーを発生させることで、ロールバックの動作を確認することも可能です。 58 // 例: throw new Exception("何らかのビジネスロジックエラーが発生しました。"); 59 60 // 5. トランザクションのコミット 61 // ここまでの全てのデータベース操作が成功したと判断し、それらを永続的にデータベースに保存します。 62 // commit() は成功した場合に true を返します。失敗した場合は通常、例外がスローされます。 63 $isCommitted = $pdo->commit(); 64 65 if ($isCommitted) { 66 echo "トランザクションが正常にコミットされました。データベースへの変更が永続化されました。\n"; 67 } else { 68 // このブロックに到達することは稀ですが、commit() が false を返した場合の備えです。 69 echo "警告: トランザクションのコミットに失敗しましたが、例外は発生しませんでした。\n"; 70 } 71 72 // 6. コミットされたデータの確認 (オプション) 73 // コミット後にデータが実際にデータベースに存在するかを確認します。 74 $stmt = $pdo->query("SELECT id, name FROM users"); 75 $users = $stmt->fetchAll(PDO::FETCH_ASSOC); // 連想配列で結果を取得 76 echo "\nコミット後の現在のユーザーデータ:\n"; 77 if (empty($users)) { 78 echo " (データなし)\n"; 79 } else { 80 foreach ($users as $user) { 81 echo " ID: " . $user['id'] . ", Name: " . $user['name'] . "\n"; 82 } 83 } 84 85 } catch (PDOException $e) { 86 // データベース関連のエラー (例: SQL構文エラー、接続失敗など) が発生した場合 87 if ($pdo && $pdo->inTransaction()) { 88 // エラー発生時にトランザクションがアクティブであれば、ロールバックを実行します。 89 // これにより、トランザクション開始以降の全ての変更が取り消されます。 90 $pdo->rollBack(); 91 echo "エラー: データベース操作中に問題が発生したため、トランザクションはロールバックされました。\n"; 92 } 93 echo "PDOException: " . $e->getMessage() . "\n"; 94 } catch (Exception $e) { 95 // その他の予期しないエラー (例: PHPのロジックエラーなど) が発生した場合 96 if ($pdo && $pdo->inTransaction()) { 97 // トランザクションがアクティブであれば、ロールバックを実行します。 98 $pdo->rollBack(); 99 echo "エラー: 予期せぬ問題が発生したため、トランザクションはロールバックされました。\n"; 100 } 101 echo "Exception: " . $e->getMessage() . "\n"; 102 } finally { 103 // データベース接続のクリーンアップ 104 // PHPスクリプトの終了時にPDOオブジェクトは自動的に破棄されますが、 105 // 明示的に null を代入することで、接続を閉じることができます。 106 $pdo = null; 107 echo "\nデータベース接続を閉じました。\n"; 108 } 109} 110 111// 関数を実行して、PDO::commit の動作を確認します。 112demonstratePdoCommitTransaction();
PHP 8のPDO::commitは、データベーストランザクションを確定し、その間の全ての変更を永続的にデータベースへ保存するメソッドです。PDO::beginTransaction()で開始された複数のデータベース操作を一つのまとまりとして扱い、全ての処理が成功した場合に限り、変更をまとめて確定します。これにより、データの一貫性を保ち、途中でエラーが発生しても部分的な変更だけがデータベースに残ることを防ぎます。
本メソッドは引数なしで、戻り値はbool型です。コミット成功時にはtrueを返しますが、通常、失敗時にはPDOExceptionがスローされます。トランザクション中にエラーが発生した際は、PDO::rollBack()を呼び出すことで、それまでの変更を全て取り消し、データベースを開始前の状態に戻すことが可能です。
提示されたサンプルコードは、インメモリSQLiteデータベースでbeginTransaction()からcommit()までの流れと、try-catchによるエラーハンドリング、rollBack()による安全な状態回復の実践例を示しており、システムエンジニアを目指す初心者がトランザクション処理の基本を学ぶのに役立ちます。
PDO::commitはPDO::beginTransactionで開始した一連のデータベース操作を確定させ、永続化します。複数の操作を一括で成功させるトランザクション処理の要です。
最も重要な注意点はエラー処理です。try-catchブロックで例外が発生した場合、必ずPDO::rollBack()を呼び出し、トランザクション開始以降の変更を取り消してください。これにより、データベースの整合性が保たれます。また、PDO::setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION)を設定することで、エラー発生時に例外がスローされ、確実なエラーハンドリングが可能になります。commit()は成功時にtrueを返しますが、例外処理と合わせて利用するのが一般的です。finallyブロックでの接続クリーンアップも推奨されます。