1. 問題の原因
MySQL の公式ドキュメントでは、ネストされたトランザクションはサポートされていないと明確に述べられています:
1. トランザクションはネストできません。これは、START TRANSACTION ステートメントまたはそのシノニムの 1 つを発行するときに、現在のトランザクションに対して実行される暗黙的なコミットの結果です。
しかし、複雑なシステムを開発する場合、たとえば、関数 A が関数 B を呼び出し、関数 A がトランザクションを使用し、関数 B もトランザクション内で呼び出されることになります。 , そのため、トランザクションのネストが発生します。この時点では、A の事柄は実際にはほとんど重要ではありません。なぜですか。上記の文書で言及されており、簡単に翻訳すると次のようになります:
1. START TRANSACTION 命令を実行すると、暗黙的にコミット操作が実行されます。 したがって、システム アーキテクチャ レベルでトランザクションのネストをサポートする必要があります。
幸いなことに、Doctrine や Laravel など、一部の成熟した ORM フレームワークではネストがサポートされています。次に、これら 2 つのフレームワークがどのように実装されているかを見てみましょう。これら 2 つのフレームワークにおける関数と変数の名前付けは比較的直感的ですが、名前を付けることで関数や変数の意味を直接知ることができるので、一見しただけではそれほど混乱する必要はありません。とても怖かったです:)
2. ドクトリンの解決策
まず、Doctrine でトランザクションを作成するコードを見てみましょう (無関係なコードは削除されました):
[php] プレーンコピーを表示
処理方法も非常に単純で、レベルが 1 の場合は、前のセーブポイントに戻るかどうかを直接ロールバックします。
[php] プレーンコピーを表示
算了,不费口舌解释段了吧 :)
三、laravel の解決策laravel の処理方法相対的单荒暴一部、我们先来看下创建事务的操作:
[php] プレーンコピーを表示
」