2016-07-15 5 views
1

Hier ist mein Code-Struktur:Wie PDO-Transaktion API funktioniert?

// db connection here 

try { 
    $dbh_conn->beginTransaction(); 

    $stm = $dbh_conn->prepare("SELECT user_id FROM resend_pass WHERE token = ?"); 
    $stm->execute(array('value')); 
    $num_rows = $stm->fetch(PDO::FETCH_ASSOC); 

    if($num_rows) { 
     echo 'one'; die; 

    } else { 
     echo 'two'; die; 

    } 

    $dbh_conn->commit(); 

} catch(PDOException $e) { 
    $dbh_conn->rollBack(); 

    echo 'three'; die; 

} 

Wann genau die Abfrage ausgeführt wird? Du weißt, mein Skript funktioniert genau wie erwartet. Aber ich frage mich wie? Wie Sie sehen, gibt es eine if - else Aussage vor commite(); Auch beide if und else haben die; in ihren Blöcken. Also soweit ich weiß, diese Linie nie ausgeführt:

$dbh_conn->commit(); 

Da es unwirsch ist ein die vor sich her. Aber überraschenderweise funktioniert auch mein Code. Hier werden alle möglichen Ausgänge:

  • Es one druckt, wenn value als Zeichen besteht in der resend_pass Tabelle.
  • Es druckt two, wenn value nicht als ein Token in der resend_pass Tabelle vorhanden ist.
  • Er druckt three, wenn ein Fehler ist (wie Syntax SQL-Fehler)

sehen? Alles gut. Aber wie? Wann genau commit() Funktion ausgeführt wird? Vor diesen die s?

Hinweis: Der Motor resend_pass ist innoDB.

+0

Wenn php beendet wird, räumt es auf, was bedeutet, dass es die Verbindung zur Datenbank unterbricht. mysql sieht das und gibt einen Rollback aus, um jeden "Müll", den die Verbindung verstreut hat, aufzuräumen. 'stirb' tötet das Skript sofort. Wenn Sie keine Shutdown-Funktion registriert haben, wird Ihr Commit-Aufruf niemals ausgeführt. –

+0

@MarcB * "Ihr Commit-Aufruf würde niemals eine Chance bekommen, ausgeführt zu werden" * - Falsch .. Wie gesagt, diese Abfrage wird ausgeführt und 'if ($ num_rows) {' führt basierend auf dem Ergebnis dieser Abfrage aus. –

+0

was ist es wichtig? PHP ist keine Zeitreise. Nur weil es irgendwo in der "Zukunft" eines Skripts einen "Die" -Befehl gibt, heißt das nicht, dass PHP es ablehnen wird, das Skript überhaupt auszuführen. Es führt den Code Zeile für Zeile aus und tut genau das, was der Code sagt. Es führt Ihre Abfrage aus. es holt ein Ergebnis.es testet das Ergebnis, DANN könnte es sterben. –

Antwort

1

Abfragen werden ausgeführt, wenn execute() aufgerufen wird (beachten Sie, dass query() Aufrufe execute()).

Wenn die Abfrage Daten in einer Tabelle ändert, die Transaktionen unterstützt, wird die Änderung rückgängig gemacht, wenn das PDO-Objekt freigegeben wird, entweder weil das Objekt den Gültigkeitsbereich verlässt oder das Skript beendet und bereinigt wird. Dies liegt an dem PDO-Code, nicht an MySQL.

Wenn die Abfrage Daten in einer Tabelle ändert, die keine Transaktionen unterstützt (z. B. eine MyISAM-Tabelle), ist die Änderung zum Zeitpunkt der Ausführung permanent und kann nicht rückgängig gemacht werden.

Es gibt einige SQL statements that perform an implicit commit. Sie würden sofort nach ihrer Ausführung dauerhaft gemacht werden, selbst wenn Ihr Skript stirbt, bevor Sie commit() anrufen.

Wie in @MarcB erwähnt, zeigt Ihr Beispiel eine schreibgeschützte SELECT-Anweisung. Es wäre einfacher, das Verhalten zu testen, wenn Sie eine INSERT/UPDATE/DELETE verwenden.

+0

Also meine aktuelle Struktur ist in Ordnung? –

+0

Ja, es ist in Ordnung. Wenn Ihr Skript 'die()' aufruft, wird die Transaktion zurückgesetzt. –

+0

Ich habe eine ziemlich ähnliche Frage. Bitte, wenn Sie etwas Freizeit haben, werfen Sie einen Blick auf http://stackoverflow.com/questions/38579529/how-my-script-rollbacks-the-queries-before-executing-rollback-function – stack