6

オンラインの php マニュアルを読みましたが、これら 2 つの関数 (mysqli::commit と mysqli::rollback) がどのように機能するかはまだわかりません。

私がしなければならない最初のことは、次のことです。

$mysqli->autocommit(FALSE);

次に、いくつかのクエリを作成します。

$mysqli->query("...");
$mysqli->query("...");
$mysqli->query("...");

次に、これら 3 つのクエリで構成されるトランザクションを次のようにコミットします。

$mysqli->commit();

しかし、これらのクエリの 1 つが機能しないという不幸なケースでは、3 つのクエリはすべてキャンセルされますか、それとも自分でロールバックを呼び出す必要がありますか? 3 つのクエリすべてをアトミックにし、1 つのクエリと見なしたいと考えています。1 つのクエリが失敗した場合、3 つすべてが失敗し、何の効果もありません。

私がこれを尋ねているのは、マニュアル ページで見たコメントの中で、http: //php.net/manual/en/mysqli.commit.php クエリの 1 つが失敗した場合、ユーザー Lorenzo がロールバックを呼び出すためです。

3 つのクエリがアトミックな場合、ロールバックは何に役立ちますか? 理解できない。

編集:これは私が疑わしいコード例です:

<?php 
$all_query_ok=true; // our control variable 
$mysqli->autocommit(false);
//we make 4 inserts, the last one generates an error 
//if at least one query returns an error we change our control variable 
$mysqli->query("INSERT INTO myCity (id) VALUES (100)") ? null : $all_query_ok=false; 
$mysqli->query("INSERT INTO myCity (id) VALUES (200)") ? null : $all_query_ok=false; 
$mysqli->query("INSERT INTO myCity (id) VALUES (300)") ? null : $all_query_ok=false; 
$mysqli->query("INSERT INTO myCity (id) VALUES (100)") ? null : $all_query_ok=false; //duplicated PRIMARY KEY VALUE 

//now let's test our control variable 
$all_query_ok ? $mysqli->commit() : $mysqli->rollback(); 

$mysqli->close(); 
?>

クエリのいずれかが失敗した場合$all_query_ok==false、トランザクションが処理されなかったためにロールバックを行う必要がないため、このコードは間違っていると思います。私は正しいですか?

4

2 に答える 2

4

InnoDBエラー処理の下に記載されているように:

のエラー処理はInnoDB、SQL 標準で指定されているものと必ずしも同じではありません。標準によれば、SQL ステートメント中にエラーが発生すると、そのステートメントがロールバックされます。InnoDBステートメントの一部のみ、またはトランザクション全体をロールバックすることがあります。InnoDB次の項目では、エラー処理を実行する方法について説明します。

  • テーブルスペースのファイル スペースが不足すると、MySQLTable is fullエラーが発生しInnoDB、SQL ステートメントがロールバックされます。

  • トランザクションのデッドロックにより、トランザクション全体InnoDBロールバックされます。これが発生した場合は、トランザクション全体を再試行してください。

    ロック待機タイムアウトにより、ロックInnoDBを待機していてタイムアウトになった単一のステートメントのみがロールバックされます。(トランザクション全体をロールバックするには、--innodb_rollback_on_timeoutオプションを使用してサーバーを起動します。) 現在の動作を使用している場合はステートメントを再試行し、 を使用している場合はトランザクション全体を再試行します--innodb_rollback_on_timeout

    ビジー状態のサーバーでは、デッドロックとロック待機タイムアウトの両方が正常に発生するため、アプリケーションはそれらが発生する可能性があることを認識し、再試行して処理する必要があります。トランザクション中のデータへの最初の変更とコミットの間の作業をできる限り少なくすることで、ロックが保持される可能性を最小限に抑えることができます。異なるトランザクション間で作業を分割することが実用的で役立つ場合があります。

    デッドロックまたはロック待ちタイムアウトによりトランザクションのロールバックが発生すると、トランザクション内のステートメントの効果がキャンセルされます。ただし、start-transaction ステートメントがSTART TRANSACTIONorBEGINステートメントの場合、ロールバックはそのステートメントをキャンセルしません。COMMIT以降の SQL ステートメントは、 、ROLLBACK、または暗黙的なコミットを引き起こす SQL ステートメントが発生するまで、トランザクションの一部になります。

  • ステートメントでオプションを指定していない場合、重複キー エラーにより SQL ステートメントがロールバックさIGNOREれます。

  • Arow too long errorは SQL ステートメントをロールバックします。

  • その他のエラーは、主にコードの MySQL レイヤー (InnoDBストレージ エンジン レベルより上) によって検出され、対応する SQL ステートメントをロールバックします。ロックは、単一の SQL ステートメントのロールバックでは解放されません。

于 2013-07-15T08:56:04.773 に答える