Werden INSERTs automatisch festgeschrieben?

13

Unsere Anwendung löst eine INSERT-Abfrage in der MySQL-Datenbank aus, um Datensätze hinzuzufügen. Ich möchte wissen, ob die Datensätze automatisch festgeschrieben werden. Wann führt die Datenbank ein Rollback durch, wenn ich den Befehl ROLLBACK ausführe? Ist ein ROLLBACK nach einem COMMIT möglich?

RPK
quelle
Zur Verdeutlichung habe ich vor 19 Stunden Innodb getaggt, da InnoDB COMMIT / ROLLBACK verwendet.
RolandoMySQLDBA
Dies wird mit +1 bewertet, um Entwickler und Datenbankadministratoren daran zu erinnern, auf das Transaktionsverhalten, die entsprechenden Anwendungsparadigmen für Transaktionen und deren Folgen (gut oder schlecht) zu achten.
RolandoMySQLDBA
Ich habe Ihre Frage mit einem Kommentar unter meiner Antwort beantwortet.
RolandoMySQLDBA

Antworten:

10

Die Antwort auf Ihre Frage hängt davon ab, ob Sie sich in einer Transaktion befinden, die mehr als eine Anweisung umfasst. (Sie haben die Frage mit InnoDB markiert, die Antwort wäre mit MyISAM anders.)

Aus dem Referenzhandbuch: http://dev.mysql.com/doc/refman/5.1/en/commit.html

Standardmäßig wird MySQL mit aktiviertem Autocommit-Modus ausgeführt. Das heißt, sobald Sie eine Anweisung ausführen, die eine Tabelle aktualisiert (ändert), speichert MySQL das Update auf der Festplatte, um es dauerhaft zu machen.

Wenn Sie also nur INSERTDatensätze verwenden, werden diese standardmäßig festgeschrieben, und es macht keinen Sinn, sie zurückzusetzen. (Dies ist praktisch dasselbe wie das Umschließen jeder Anweisung zwischen BEGINund COMMIT.)

Wenn Sie sich jedoch explizit mit Transaktionen befassen, müssen Sie das COMMITCommit zum Speichern der Datensätze verwenden, können es jedoch auch verwenden ROLLBACK.

Sie können eine Transaktion explizit mit START TRANSACTION(oder BEGIN) starten . Dies ist unabhängig von der autocommitEinstellung (standardmäßig aktiviert):

Bei START TRANSACTION bleibt das Autocommit deaktiviert, bis Sie die Transaktion mit COMMIT oder ROLLBACK beenden. Der Autocommit-Modus kehrt dann zu seinem vorherigen Zustand zurück.

Wenn autocommit=0ich der Meinung bin, dass eine Anweisung nach einem anderen Transaktionsende eine Transaktion startet, können Sie diese auch START TRANSACTIONexplizit verwenden. so interpretiere ich das jedenfalls :

Der Autocommit-Modus. Wenn der Wert auf 1 gesetzt ist, werden alle Änderungen an einer Tabelle sofort wirksam. Bei 0 müssen Sie COMMIT verwenden, um eine Transaktion zu akzeptieren, oder ROLLBACK, um sie abzubrechen. Wenn das automatische Festschreiben 0 ist und Sie es in 1 ändern, führt MySQL ein automatisches Festschreiben aller offenen Transaktionen durch. Eine andere Möglichkeit, eine Transaktion zu starten, ist die Verwendung einer START TRANSACTION- oder BEGIN-Anweisung. Siehe auch Abschnitt 12.3.1, „START TRANSACTION, COMMIT und ROLLBACK-Syntax“.

Genauer gesagt scheint "ein anderer Weg, eine Transaktion zu beginnen" zu implizieren, dass das Setzen von "autocommit = 0" ausreicht, um eine Transaktion zu starten (zumindest kurz vor jeder Anweisung beim Start einer Sitzung oder nach einem COMMIT/ ROLLBACK). Ich würde vorschlagen, BEGINoder START TRANSACTIONexplizit zu verwenden, auch wenn autocommit=0, da es klarer machen kann, wann die Transaktion beginnt oder endet.

(Wie Sie eine Transaktion starten, hängt möglicherweise davon ab, wie Ihre Anwendung MySQL verwendet.)

Bruno
quelle
1
Verdient eine +1 für die vollständige Definition von Transaktionsprotokollen.
RolandoMySQLDBA
@Bruno, für MyISAM, wo "Festschreiben" und "Zurücksetzen" nicht funktionieren, wären die Einfügungen nicht zur Hälfte festgeschrieben?
Pacerier
7

Standardmäßig ist InnoDB auf autocommit = 1 oder ON eingestellt . Einmal festgeschrieben, können sie nicht zurückgesetzt werden .

Sie müssten eines von zwei Dingen tun, um es zukünftig zu deaktivieren:

OPTION 1: Fügen Sie dies zu /etc/my.cnf hinzu und starten Sie mysql neu

[mysqld]
autocommit=0

OPTION 2: Führen Sie eine dieser Aktionen in der Open DB Conenction aus, bevor Sie mit einer aussagekräftigen SQL-Operation beginnen

SET autocommit = 0;
START TRANSACTION;

Unter diesen beiden Optionen müssten Sie ein manuelles COMMIT oder ein manuelles ROLLBACK durchführen .

VORBEHALT

Wenn die Tabelle MyISAM ist, ist die Erklärung einfacher. Da für die MyISAM-Speicher-Engine keine Transaktionen vorhanden sind, sind alle ausgeführten INSERT-, UPDATE- und DELETE-Operationen permanent. Keine Rollbacks.

RolandoMySQLDBA
quelle
Zur weiteren Verdeutlichung befasst sich meine Antwort sowohl mit InnoDB- als auch mit MyISAM-Speicher-Engines.
RolandoMySQLDBA
1
Wie schnell gehen die Änderungen verloren, wenn Auto Commit in InnoDB deaktiviert ist und meine Anwendung Insert Queries auslöst und ich vergesse, das Commit auszuführen?
RPK
Wenn Ihre Anwendung nach jedem EINFÜGEN manuell ein COMMIT auslöst, wird es geschrieben und kann nicht gelöscht werden. Wenn die DB-Verbindung unterbrochen wird, bevor Sie ein COMMIT ausführen, gehen alle Änderungen verloren und es erfolgt ein Rollback. Wenn Sie eine DDL (CREATE TABLE, DROP TABLE, ALTER TABLE usw.) ausführen oder manuell eine Tabellensperre auslösen, werden die INSERTs automatisch festgeschrieben. Wenn Sie START TRANSACTION verwenden, werden alle nicht festgeschriebenen Änderungen festgeschrieben.
RolandoMySQLDBA
1
Zu "Wenn Sie START TRANSACTION verwenden, werden alle nicht festgeschriebenen Änderungen festgeschrieben." (im Kontext von DDLs, andernfalls würde es zurückgesetzt), gibt es auch ein implizites Commit vor (das implizite Commit nach ist ab Version 5.5.3 laut Dokumentation).
Bruno
1
"Wenn Sie START TRANSACTION verwenden, werden alle nicht festgeschriebenen Änderungen festgeschrieben." - Ich habe diese Idee aus dem MySQL 5.0-Handbuch für Zertifizierungsstudien (ISBN 0-672-32812-7), das START TRANSACTION, SET AUTOCOMMIT = 1, LOCK TABLES, UNLOCK TABLES, TRUNCATE TABLE, RENAME TABLE, DROP INDEX, DROP TABLE nennt , DROP DATABASE, CREATE INDEX, BEGIN und ALTER TABLE unter den Überschriften "Unter bestimmten Umständen wird die aktuelle Transaktion implizit beendet: Wenn Sie eine der folgenden Anweisungen ausgeben, schreibt InnoDB die vorhergehenden nicht festgeschriebenen Anweisungen der aktuellen Transaktion implizit fest und beginnt a neue Transaktion ".
RolandoMySQLDBA