ホームページ >バックエンド開発 >PHPの問題 >PDO を使用して PHP でトランザクションを操作する方法

PDO を使用して PHP でトランザクションを操作する方法

醉折花枝作酒筹
醉折花枝作酒筹転載
2021-06-21 15:17:481590ブラウズ

この記事では、PDO を使用して PHP でトランザクションを操作する方法を紹介します。一定の参考値があるので、困っている友達が参考になれば幸いです。

PDO を使用して PHP でトランザクションを操作する方法

# トランザクションの問題については、これ以上は説明しませんが、今後、MySQL の関連内容を学習する際にさらに詳しく知ることになります。今日は主に PDO でのトランザクション操作に関する小規模なテストを行っており、興味深い内容が見つかるかもしれません。

MyISAM でトランザクションを使用するとどうなりますか?

まず、MySQL について少し学んだ人なら、MySQL で一般的に使用される 2 つのテーブル タイプが InnoDB と MyISAM であることをご存知だと思います。もちろん、今日はそのすべての違いについて説明するつもりはありませんが、最も明白な違いが 1 つあります。それは、MyISAM がトランザクションをサポートしていないということです。では、PDO 操作内で MyISAM に対してトランザクション操作を実行するとどうなるでしょうか?

// myisam
try {
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->beginTransaction();
    $pdo->exec("insert into tran_myisam (name, age) values ('Joe', 12)");
    $pdo->exec("insert into tran_myisam2 (name, age) values ('Joe', 12, 33)");

    // sleep(30);
    $pdo->commit();

} catch (Exception $e) {
    $pdo->rollBack();
    echo "Failed: " . $e->getMessage(), PHP_EOL;
}

tran_myisam テーブルと tran_myisam2 テーブルは両方とも MyISAM タイプのテーブルです。このコードでは、意図的に tran_myisam2 の間違った挿入ステートメントを記述し、それをキャッチに入れています。実際の実行結果は、エラーメッセージが正常に出力され、tran_myisam テーブルのデータも挿入されます。つまり、MyISAM テーブルに対するトランザクション操作は効果がありません。もちろん、PDO はエラーを積極的に報告しません。2 番目の SQL ステートメントを通常のステートメントにすると、PDO はエラーやプロンプトを表示せずに正常に終了するだけです。

// innodb
try {
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->beginTransaction();
    $pdo->exec("insert into tran_innodb (name, age) values ('Joe', 12)");
    $pdo->exec("insert into tran_innodb2 (name, age) values ('Joe', 12, 3)");
    // sleep(30);
    $pdo->commit();

} catch (Exception $e) {
    $pdo->rollBack();
    echo "Failed: " . $e->getMessage(), PHP_EOL;
}

sleep(30); このコード行のコメントを開いて、トランザクションがコミットされる前に 30 秒間一時停止してから、MySQL の infomation_schema.INNODB_TRX テーブルを表示します。この表に示されているのは、実行中のトランザクションです。 InnoDB タイプのテーブルを実行すると、実行中のトランザクションの記録が表示されますが、MyISAM タイプのテーブルには情報が表示されません。

トランザクションがコミットまたはロールバックされなかった場合はどうなりますか?

commit() を書き忘れてエラーが報告されなかったとします。このステートメントは正常に実行されるでしょうか?以下のコードのように。

try {
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->beginTransaction();
    $pdo->exec("insert into tran_innodb (name, age) values ('Joe', 12)");
    $pdo->exec("insert into tran_innodb2 (name, age) values ('Joe', 12)");

    // 忘记写 $pdo->commit(); 了
} catch (Exception $e) {
    $pdo->rollBack();
    echo "Failed: " . $e->getMessage(), PHP_EOL;
}

PHP は、スクリプトの実行が終了した後、実際には $pdo オブジェクトが破棄されたときにこのトランザクションをロールバックします。つまり、ここでの SQL ステートメントは実行されません。ただし、正式な環境ではコードが非常に複雑で、正常に破棄できない可能性があるため、これは行わないでください。この場合、長時間かかるトランザクションが発生する可能性があり、最終的には MySQL の IPQS が非常に高くなり、その原因を見つけるのが困難になります。したがって、トランザクションを使用するときは、commit() と rollBack() が兄弟であり、取り残されてはならないことを覚えておく必要があります。

前のトランザクションはコミットまたはロールバックされませんでした。次のトランザクションは実行されますか?

同様に、前の質問に基づいて拡張を続けます。 2 つのトランザクションが連続して実行され、最初のトランザクションがコミットまたはロールバックされなかった場合、次のトランザクションは引き続き実行できますか?

// innodb
try {
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->beginTransaction();
    $pdo->exec("insert into tran_innodb (name, age) values ('Joe', 12)");
    $pdo->exec("insert into tran_innodb2 (name, age) values ('Joe', 12)");
    // 忘记写 $pdo->commit(); 了
} catch (Exception $e) {
    $pdo->rollBack();
    echo "Failed: " . $e->getMessage(), PHP_EOL;
}

// innodb
try {
    $pdo->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
    $pdo->beginTransaction();
    $pdo->exec("insert into tran_innodb (name, age) values ('BW', 12)");
    $pdo->exec("insert into tran_innodb2 (name, age) values ('BW', 12)");

    // sleep(30);
    $pdo->commit();
} catch (Exception $e) {
    $pdo->rollBack();
    echo "Failed: " . $e->getMessage(), PHP_EOL; // Failed: There is already an active transaction
}

2 番目のトランザクションがエラーを直接報告していることがわかります。その内容は、「ここに既存のアクティブなトランザクションがあります。」です。つまり、前のトランザクションがコミットまたはロールバックされていない場合、2 番目のトランザクションは実行できません。

概要

今日は、トランザクションに関連するいくつかの小さな問題を学習し、テストしましたが、問題は小さいとはいえ、重大なオンライン事故を引き起こす可能性があります。開発するとき。トランザクションの詳細については、今後 MySQL を詳しく学習するときに学習します。

テスト コード:

https://github.com/zhangyue0503/dev-blog/blob/master/php/202008/source/PHP中使用PDO操作事务的一些小测试.php

推奨学習: php ビデオ チュートリアル

以上がPDO を使用して PHP でトランザクションを操作する方法の詳細内容です。詳細については、PHP 中国語 Web サイトの他の関連記事を参照してください。

声明:
この記事はsegmentfault.comで複製されています。侵害がある場合は、admin@php.cn までご連絡ください。