PDO を介して接続したので、クエリを開始する前に、まず PDO がトランザクションを管理する方法を理解する必要があります。
トランザクションは 4 つの主要な特性 (ACID) をサポートします。
原子性
一貫性
分離
耐久性
平たく言えば、トランザクション内で実行される操作は、段階的に実行される場合でも、他の接続からの干渉なしに安全にデータベースに適用され、コミットされることが保証されます。
トランザクション操作はリクエストに応じて自動的に元に戻すこともできるため (まだコミットされていないことが前提)、スクリプトでのエラーの処理が容易になります。
トランザクションは通常、変更のバッチを「蓄積」し、同時にそれらを有効にすることによって実装されます。これを行う利点は、これらの変更の効率を大幅に向上できることです。
言い換えれば、トランザクションによってスクリプトが高速化され、潜在的により堅牢になる可能性があります (ただし、そのような利点を得るにはトランザクションを正しく使用する必要があります)。
残念ながら、すべてのデータベースがトランザクションをサポートしているわけではないため、最初に接続を開いたときに PDO をいわゆる「自動コミット」モードで実行する必要があります。
オートコミット モードは、データベースがトランザクションをサポートしている場合は各クエリ実行に独自の暗黙的なトランザクションがあり、データベースがトランザクションをサポートしていない場合はトランザクションが存在しないことを意味します。
トランザクションが必要な場合は、PDO::beginTransaction() メソッドで開始する必要があります。基礎となるドライバーがトランザクションをサポートしていない場合、PDOException がスローされます (これは、エラー処理設定に関係なく、重大なエラー状態です)。
トランザクションが開始されると、トランザクション内のコードが正常に実行されたかどうかに応じて、PDO::commit() または PDO::rollBack() を使用してトランザクションを完了できます。
注: PDO は、ドライバー レベルでトランザクション機能があるかどうかのみをチェックします。実行時条件によってトランザクションが利用できないことを意味し、データベース サービスがトランザクション開始リクエストを受け入れた場合でも、PDO::beginTransaction() はエラーなしで TRUE を返します。良い例は、MySQL データベースの MyISAM テーブルでトランザクションを使用しようとすることです。
スクリプトが終了するか、接続が閉じられようとしているときに、未処理のトランザクションがある場合、PDO はトランザクションを自動的にロールバックします。この安全対策は、スクリプトが予期せず終了した場合の不整合を回避するのに役立ちます。トランザクションが明示的にコミットされていない場合は、何か問題が発生したと想定されるため、データを安全に保つためにロールバックが実行されます。
注:自動ロールバックは、PDO::beginTransaction() によってトランザクションを開始した後にのみ発生する可能性があります。トランザクションを開始するクエリを手動で発行した場合、PDO はそれを知る方法がないため、必要に応じてロールバックできません。
トランザクション内でバッチ処理を実行します。
次の例では、新しい従業員用に一連のエントリが作成され、ID 23 が割り当てられると想定しています。個人の基本データを登録することに加えて、給与も記録する必要があります。
両方の更新を個別に行うのは簡単ですが、それらを PDO::beginTransaction() 呼び出しと PDO::commit() 呼び出しで囲むことで、完了するまで他の人が変更を確認できないようにすることができます。
エラーが発生した場合、catch ブロックはトランザクションの開始以降に発生したすべての変更をロールバックし、エラー メッセージを出力します。
<?phptry { $dbh = new PDO('odbc:SAMPLE', 'db2inst1', 'ibmdb2', array(PDO::ATTR_PERSISTENT => true)); echo "接続済みn";} catch (Exception $e) { die("接続できません: " . $e->getMessage());}try { $dbh->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION); $dbh->beginTransaction() $dbh->exec("スタッフ (id, first, last) 値に挿入 (23, 'ジョー) ', 'ブログ')"); $dbh->exec("給与変更 (ID, 金額, 変更日) 値に挿入 (23, 50000, NOW())"); $dbh->commit(); } catch (Exception $e) { $dbh->rollBack(); echo "失敗しました: " . $e->getMessage();}?>
トランザクション内での変更に限定されず、複雑なクエリを発行してデータを抽出することもでき、トランザクションがアクティブなときにその情報を使用してさらに変更やクエリを作成することもでき、トランザクション中に他のユーザーが変更を加えられないことを保証できます。操作が進行中です。