Unterschied zwischen SET autocommit = 1 und START TRANSACTION in MySQL (Habe ich etwas verpasst?)

78

Ich lese über Transaktionen in MySQL und bin mir nicht sicher, ob ich etwas Bestimmtes richtig verstanden habe, und ich möchte sicher sein, dass ich das richtig verstanden habe. Ich weiß, was eine Transaktion tun soll, ich bin mir nur nicht sicher, ob ich die Anweisungssemantik verstanden habe oder nicht.

Meine Frage ist also, ob irgendetwas falsch ist (und wenn dies der Fall ist, was ist falsch), und zwar mit Folgendem:

Standardmäßig ist der Autocommit-Modus in MySQL aktiviert.

Jetzt SET autocommit=0;beginnt eine Transaktion, SET autocommit=1;wird implizit festgeschrieben. Es ist möglich, COMMIT;als auch ROLLBACK;, in welche beide Fälle autoCommit noch danach auf 0 gesetzt ist (und eine neue Transaktion implizit gestartet).

START TRANSACTION;wird grundsätzlich SET autocommit=0;bis ein COMMIT;oder ROLLBACK;stattfindet.

Mit anderen Worten, START TRANSACTION;und SET autocommit=0;sind äquivalent, mit Ausnahme der Tatsache, dass START TRANSACTION;dies dem impliziten Hinzufügen eines SET autocommit=0;Nachher COMMIT;oder Oder entsprichtROLLBACK;

Wenn dies der Fall ist, verstehe ich http://dev.mysql.com/doc/refman/5.5/en/set-transaction.html#isolevel_serializable nicht - da eine Isolationsstufe impliziert, dass es eine Transaktion gibt, was bedeutet, dass Autocommit sowieso ausgeschaltet sein sollte?

Und wenn es einen anderen Unterschied (als den oben beschriebenen) zwischen dem Starten einer Transaktion und dem Festlegen der automatischen Festschreibung gibt, was ist das?

ralokt
quelle

Antworten:

79

Wenn Sie sich der Transaktionsbehandlung (Autocommit, explizit und implizit) für Ihre Datenbank bewusst sind, müssen Sie möglicherweise keine Daten aus einer Sicherung wiederherstellen.

Transaktionen steuern Datenmanipulationsanweisungen, um sicherzustellen, dass sie atomar sind. "Atomic" zu sein bedeutet, dass die Transaktion entweder stattfindet oder nicht. Die einzige Möglichkeit, den Abschluss der Transaktion an die Datenbank zu signalisieren, ist die Verwendung einer Anweisung COMMIToder ROLLBACK(gemäß ANSI-92, das leider keine Syntax zum Erstellen / Starten einer Transaktion enthielt, sodass diese herstellerspezifisch ist). COMMITwendet die im Rahmen der Transaktion vorgenommenen Änderungen (falls vorhanden) an. ROLLBACKignoriert alle Aktionen, die innerhalb der Transaktion stattgefunden haben - sehr wünschenswert, wenn eine UPDATE / DELETE-Anweisung etwas Unbeabsichtigtes tut .

In der Regel werden einzelne DML-Anweisungen (Einfügen, Aktualisieren, Löschen) in einer Autocommit-Transaktion ausgeführt. Sie werden festgeschrieben, sobald die Anweisung erfolgreich abgeschlossen wurde. Dies bedeutet, dass es keine Möglichkeit gibt, die Datenbank auf den Status zurückzusetzen, bevor die Anweisung in Fällen wie Ihrem ausgeführt wurde. Wenn etwas schief geht, besteht die einzige verfügbare Wiederherstellungsoption darin, die Daten aus einer Sicherung zu rekonstruieren (sofern eine vorhanden ist). In MySQL ist autocommit auf standardmäßig für InnoDB - MyISAM unterstützt keine Transaktionen. Es kann deaktiviert werden mit:

SET autocommit = 0

Eine explizite Transaktion liegt vor, wenn Anweisungen in einen explizit definierten Transaktionscodeblock eingeschlossen werden - für MySQL alsoSTART TRANSACTION . Es erfordert auch eine explizite Abgabe COMMIToder ROLLBACKErklärung am Ende der Transaktion. Verschachtelte Transaktionen gehen über den Rahmen dieses Themas hinaus.

Implizite Transaktionen unterscheiden sich geringfügig von expliziten. Implizite Transaktionen erfordern keine explizite Definition einer Transaktion. Wie bei expliziten Transaktionen muss jedoch eine COMMIToder ROLLBACK-Erklärung angegeben werden.

Fazit

Explizite Transaktionen sind die idealste Lösung - sie erfordern eine Erklärung COMMIToder ROLLBACK, um die Transaktion abzuschließen, und was passiert, ist klar angegeben, damit andere es lesen können, wenn es nötig ist. Implizite Transaktionen sind in Ordnung, wenn Sie interaktiv mit der Datenbank arbeiten. COMMITAnweisungen sollten jedoch erst angegeben werden, wenn die Ergebnisse getestet und gründlich als gültig bestimmt wurden.

Das heißt, Sie sollten verwenden:

SET autocommit = 0;

START TRANSACTION;
  UPDATE ...;

... und nur verwenden, COMMIT;wenn die Ergebnisse korrekt sind.

Allerdings geben UPDATE- und DELETE-Anweisungen normalerweise nur die Anzahl der betroffenen Zeilen zurück, nicht bestimmte Details. Konvertieren Sie solche Anweisungen in SELECT-Anweisungen und überprüfen Sie die Ergebnisse, um die Richtigkeit sicherzustellen, bevor Sie die UPDATE / DELETE-Anweisung ausführen.

Nachtrag

DDL-Anweisungen (Data Definition Language) werden automatisch festgeschrieben - sie erfordern keine COMMIT-Anweisung. IE: Anweisungen zum Erstellen oder Ändern von Tabellen, Indizes, gespeicherten Prozeduren, Datenbanken und Ansichten.

OMG Ponys
quelle
9
Wow, das ging schnell :-) Vielen Dank! Was ich nicht ganz verstehe, ist, warum ich autocommit = 0 setzen muss; im obigen Beispiel; Bedeutet das Starten einer Transaktion nicht, dass? Und wenn nicht, was ist der Unterschied?
Ralokt
1
@tkolar: Durch Deaktivieren der automatischen Festschreibung werden alle zur Verwendung von START TRANSACTION gezwungen. Nicht jeder weiß, dass er es verwenden sollte. Natürlich könnte ein anderer DBA es auch wieder einschalten ...
OMG Ponies
3
Ich denke zu haben SET autocommit = 0;ist nur eine Präferenz, um nicht zu vergessen, Transaktionen zu verwenden
Timo Huovinen
Wenn ich also eine Transaktion explizit mit starte START TRANSACTION, muss ich auch explizit angeben COMMIT, dass Autocommit aktiviert ist. Ist es?
Tomwang1013
In verschachtelter gespeicherter Prozedur Aufruf. Was soll ich verwenden @OMGPonies
Selvakumar
20

In InnoDB haben Sie START TRANSACTION;, was in dieser Engine die offiziell empfohlene Methode zum Ausführen von Transaktionen ist, anstatt SET AUTOCOMMIT = 0;(nicht SET AUTOCOMMIT = 0;für Transaktionen in InnoDB verwenden, es sei denn, es dient zur Optimierung von schreibgeschützten Transaktionen). Commit mit COMMIT;.

Vielleicht haben Sie verwenden möchten , SET AUTOCOMMIT = 0;in InnoDB zu Testzwecken und nicht gerade für Transaktionen.

In MyISAM haben Sie nicht START TRANSACTION;. In dieser Engine SET AUTOCOMMIT = 0;für Transaktionen verwenden. Festschreiben mit COMMIT;oder SET AUTOCOMMIT = 1;(Unterschied im folgenden MyISAM-Beispielkommentar erläutert). Auf diese Weise können Sie auch in InnoDB Transaktionen durchführen.

Quelle: http://dev.mysql.com/doc/refman/5.6/en/glossary.html#glos_autocommit

Beispiele für Transaktionen mit allgemeiner Verwendung:

/* InnoDB */
START TRANSACTION;

INSERT INTO table_name (table_field) VALUES ('foo');
INSERT INTO table_name (table_field) VALUES ('bar');

COMMIT; /* SET AUTOCOMMIT = 1 might not set AUTOCOMMIT to its previous state */

/* MyISAM */
SET AUTOCOMMIT = 0;

INSERT INTO table_name (table_field) VALUES ('foo');
INSERT INTO table_name (table_field) VALUES ('bar');

SET AUTOCOMMIT = 1; /* COMMIT statement instead would not restore AUTOCOMMIT to 1 */
mikl
quelle
1

https://dev.mysql.com/doc/refman/8.0/en/lock-tables.html

Die korrekte Verwendung von LOCK TABLES und UNLOCK TABLES mit Transaktionstabellen wie InnoDB-Tabellen besteht darin, eine Transaktion mit SET autocommit = 0 (nicht START TRANSACTION) gefolgt von LOCK TABLES zu beginnen und UNLOCK TABLES erst aufzurufen, wenn Sie die Transaktion festschreiben ausdrücklich. Wenn Sie beispielsweise in Tabelle t1 schreiben und aus Tabelle t2 lesen müssen, können Sie Folgendes tun:

SET autocommit=0;
LOCK TABLES t1 WRITE, t2 READ, ...;... do something with tables t1 and t2 here ...
COMMIT;
UNLOCK TABLES;
Marco Aurelio Curado
quelle
Weiß jemand, warum genau Tabellenschlösser nur funktionieren, autocommit=0aber nicht mit START TRANSACTION? Es scheint mir völlig willkürlich. Gibt es einen technischen Grund?
10.
1

Wenn Sie Rollback verwenden möchten, verwenden Sie Transaktion starten und sonst alle diese Dinge vergessen,

Standardmäßig schreibt MySQL die Änderungen automatisch in die Datenbank.

Führen Sie Folgendes aus, um MySQL zu zwingen, diese Änderungen nicht automatisch festzuschreiben:

SET autocommit = 0;
//OR    
SET autocommit = OFF

So aktivieren Sie den Autocommit-Modus explizit:

SET autocommit = 1;
//OR    
SET autocommit = ON;
RINSON KE
quelle