mysqli::commit() und ::rollback()

Einklappen
X
 
  • Filter
  • Zeit
  • Anzeigen
Alles löschen
neue Beiträge

  • mysqli::commit() und ::rollback()

    Ich verstehe folgendes Beispiel aus dem PHP-Manual nicht ganz:

    PHP-Code:
      <?php
    $mysqli 
    = new mysqli("localhost""my_user""my_password""world");

    /* check connection */
    if (mysqli_connect_errno()) {
        
    printf("Connect failed: %s\n"mysqli_connect_error());
        exit();
    }

    /* disable autocommit */
    $mysqli->autocommit(FALSE);

    $mysqli->query("CREATE TABLE myCity LIKE City");
    $mysqli->query("ALTER TABLE myCity Type=InnoDB");
    $mysqli->query("INSERT INTO myCity SELECT * FROM City LIMIT 50");

    /* commit insert */
    $mysqli->commit();

    /* delete all rows */
    $mysqli->query("DELETE FROM myCity");

    if (
    $result $mysqli->query("SELECT COUNT(*) FROM myCity")) {
        
    $row $result->fetch_row();
        
    printf("%d rows in table myCity.\n"$row[0]);
        
    /* Free result */
        
    $result->close();
    }

    /* Rollback */
    $mysqli->rollback();

    if (
    $result $mysqli->query("SELECT COUNT(*) FROM myCity")) {
        
    $row $result->fetch_row();
        
    printf("%d rows in table myCity (after rollback).\n"$row[0]);
        
    /* Free result */
        
    $result->close();
    }

    /* Drop table myCity */
    $mysqli->query("DROP TABLE myCity");

    $mysqli->close();
    ?>
    The above example will output:
    0 rows in table myCity.
    50 rows in table myCity (after rollback).

    Zuerst wird ja mit ->autocommit(false) das automatische Ausführen von Queries ausgeschaltet, oder? Dann werden drei Query-Befehle spezifiziert, die danach mit ->commit() ausgeführt werden, richtig? Die nachfolgende Query "DELETE.." sollte dann aber doch nicht ausgeführt werden, weil ->autocommit ja noch auf false ist? Und dann sollte andererseits mit ->rollback() nicht die Delete-Aufforderung rückgängig gemacht werden, sondern die "CREATE TABLE"-Aufforderung, oder nicht?


    </div> </div>

  • #2
    Zitat von tim-gt Beitrag anzeigen
    Zuerst wird ja mit ->autocommit(false) das automatische Ausführen von Queries ausgeschaltet, oder?
    Es wird nicht mehr automatisch nach jeder abgesetzten Query committed, ja.

    Dann werden drei Query-Befehle spezifiziert, die danach mit ->commit() ausgeführt werden, richtig?
    Genau, die werden nicht automatisch und sofort ausgeführt, sobald sie per mysqli->query an die DB übergeben wurden, sondern erst mal "auf Halde gelegt" - und dann zumsammen in einer Transaktion abgearbeitet, sobald du mit commit die Anweisung dazu gibst.

    Die nachfolgende Query "DELETE.." sollte dann aber doch nicht ausgeführt werden, weil ->autocommit ja noch auf false ist?
    Ja, meinem Verständnis nach sollte es sich so verhalten.

    Siehe auch http://www.php.net/manual/en/mysqli.commit.php#89976:
    Please note that calling mysqli::commit() will NOT automatically set mysqli::autocommit() back to 'true'.

    This means that any queries following mysqli::commit() will be rolled back when your script exits.


    Und dann sollte andererseits mit ->rollback() nicht die Delete-Aufforderung rückgängig gemacht werden, sondern die "CREATE TABLE"-Aufforderung, oder nicht?
    Puh, da bin ich gerade überfragt.

    Aber ich sehe das auch so, dass da hinter das DELETE erst noch mal ein COMMIT hingehören müsste, damit das Script sich wie beschrieben verhält.
    I don't believe in rebirth. Actually, I never did in my whole lives.

    Kommentar


    • #3
      Zitat von tim-gt Beitrag anzeigen
      Und dann sollte andererseits mit ->rollback() nicht die Delete-Aufforderung rückgängig gemacht werden, sondern die "CREATE TABLE"-Aufforderung, oder nicht?
      Ne, das create table-Statement ist bereits commited worden, d.h. danach wird eine neue Transaktion begonnen, du rollst also nur das Delete zurück. Ich war mir erst nicht ganz sicher ob das drop table überhaupt ausgeführt wird, wenn danach kein commit mehr folgt. Aber in den Usercomments zu autocommit habe ich den passenden Hinweis gefunden:

      CREATE TABLE and CREATE DATABASE (and probably others) are always commited immediately and your transaction appears to terminate. Thus any commands before and after will be commited, even if a subsequent rollback is attempted.

      If you are in the middle of a transaction and you call mysqli_close() it appears that you get the funcitonality of an implicit rollback.
      Das heißt, eigentlich müsste das Löschen der Tabelle zurückgerollt werden, das Drop table wird aber wohl wie create table implizit die Transaktion abschicken.

      Kommentar


      • #4
        Aha, dann ist es so, dass auch bei autocommit(false) alle Queries einfach mal "ausgeführt" werden, aber einfach nicht definitiv? mysqli::commit würde dann das ganze in "Stein meisseln", und rollback würde es rückgängig machen?
        Wäre autocommit(true), dann wäre der Gebrauch von commit und rollback sinnlos, da eben commit sowieso immer gleich befohlen würde?
        Macht eigentlich noch Sinn... und gewisse Statements kann man dann wohl nicht mehr zurückrollen, wie eben Create oder Drop Table.

        Kommentar


        • #5
          Zitat von tim-gt Beitrag anzeigen
          Aha, dann ist es so, dass auch bei autocommit(false) alle Queries einfach mal "ausgeführt" werden, aber einfach nicht definitiv?
          Innerhalb deiner Transaktion werden diese ausgeführt, d.h. ein truncate table und ein nachträgliches select liefert keine Daten, nach einem Rollback ist die Tabelle aber dennoch nicht leer.

          mysqli::commit würde dann das ganze in "Stein meisseln", und rollback würde es rückgängig machen?
          Richtig.
          Wäre autocommit(true), dann wäre der Gebrauch von commit und rollback sinnlos, da eben commit sowieso immer gleich befohlen würde?
          Richtig.
          Macht eigentlich noch Sinn... und gewisse Statements kann man dann wohl nicht mehr zurückrollen, wie eben Create oder Drop Table.
          Richtig.

          Kommentar


          • #6
            Zitat von tim-gt Beitrag anzeigen
            und gewisse Statements kann man dann wohl nicht mehr zurückrollen, wie eben Create oder Drop Table.
            Transaktionen dienen dazu, einzelne Statements zusammenzufassen, die wenn eins davon schief ginge, die Konsistenz der Daten kompromitieren würden - Einfügen von Datensätzen über mehrere Tabellen hinweg, die Fremdschlüssel berühren, etc. Wenn dann auffällt, dass eins davon fehlerhaft war, rollt man alles zurück, und hat nach wie vor konsitente Daten.

            CREATE oder DROP hingegen haben nichts mit Konsistenz zu tun; deshalb wäre da die Möglichkeit eines Roolback eher unsinnig, es soll schliesslich kein komplettes Backup ersetzen.
            I don't believe in rebirth. Actually, I never did in my whole lives.

            Kommentar

            Lädt...
            X