Frage Ist Join insert / update auf MySQL eine atomare Operation?


Werden Abfragen mit Unterabfragen und / oder Verknüpfungen in einer Mysql-Datenbank mit jeder Tabelle, die auf InnoDB mit aktiviertem Autocommit basiert, atomar?

Beispiele:

  • INSERT INTO users SELECT (x,y,z) FROM users, comments WHERE users.id = comments.user_id;  (verbindet)

  • UPDATE users, comments SET users.x = x1 WHERE users.age > 30; (verbindet)

  • UPDATE users, comments SET users.x = x1, comments.y = y1 WHERE users.age > 30; (verbindet)

  • UPDATE users, comments SET users.x = x1, comments.y = y1 WHERE users.id IN (SELECT id FROM users WHERE age > 30); (Unterabfragen)


5
2017-10-18 08:07


Ursprung


Antworten:


Ich verstehe Ihre Frage wie "ist jede dieser Fragen an sich eine atomare Operation?". Dann lautet die Antwort "Ja". Die anderen beiden Antworten haben Recht, wenn sie sagen, dass alle Ihre Aussagen zusammen nicht atomar sind.

Atomarität in Datenbanken bedeutet nur alles oder nichts. Es bedeutet nicht Richtigkeit der Daten Ihre Aussage ist erfolgreich oder nicht. Es hat nichts mit Joins oder Unterabfragen zu tun. Eine Anweisung ist eine Anweisung, unabhängig davon, ob Ihre Datenbank eine temporäre Tabelle im Speicher oder auf der Festplatte verwenden muss oder nicht.

Transaktionen weisen Ihre Datenbank nur an, mehrere Anweisungen als eine Anweisung zu behandeln. Wenn eine der Anweisungen fehlschlägt, werden alle zurückgesetzt.

Ein wichtiges verwandtes Thema hier ist die Isolationsstufe. Vielleicht möchten Sie darüber nachlesen.

EDIT (um den Kommentar zu beantworten):

Stimmt. Solange es eine gültige Aussage ist und kein Stromausfall auftritt oder andere Gründe, warum eine Abfrage fehlschlagen könnte, wird es gemacht. Atomarität an sich garantiert nur, dass die Aussage (n) gemacht wird / werden oder nicht. Es garantiert Vollständigkeit und dass Daten nicht beschädigt sind (weil ein Schreibvorgang nicht abgeschlossen wurde oder so). Es garantiert nicht die Richtigkeit der Daten. Gegeben eine Abfrage wie INSERT INTO foo SELECT MAX(id) + 1 FROM bar; Sie müssen sicherstellen, über die richtige Einstellung Isolationsstufe, dass Sie keine Phantom-Lesevorgänge oder ähnliches erhalten.


6
2017-10-18 08:32



Nein, es sei denn, Sie wickeln sie ein START TRANSACTION so was

START TRANSACTION;
   SELECT @A:=SUM(salary) FROM table1 WHERE type=1;
   UPDATE table2 SET summary=@A WHERE type=1; 
COMMIT;

Beispiel aus Mysql Handbuch


4
2017-10-18 08:17



Ihre SQL-Anweisungen werden nicht automatisch mit Autocommit ausgeführt. Sie müssen eine Transaktion starten, um Autocommit deaktiviert zu haben. Sehen http://dev.mysql.com/doc/refman/5.0/de/commit.html


3
2017-10-18 08:14



Ich weiß es nicht, und ich erkläre dir warum. Ich hatte ein wirklich seltsames Problem mit MySQL.

Stellen Sie sich vor, Sie haben eine Tabelle namens "table1" mit einem einzigen Datensatz. Spalte f1 hat einen Wert von "A". Spalte f2 hat einen Wert von "B"

Update table1 set f1 = CONCAT(f1,f2), f2 = 'C';

Der endgültige Wert von f1 ist wie erwartet 'AB'.

Aber wenn Sie die Reihenfolge ändern:

Update table1 set f2 = 'C', f1 = CONCAT(f1,f2);

Der endgültige Wert von f1 ist 'AC'. Das heißt: f2 wird zuerst geändert und danach f1.

Meine Schlussfolgerung ist, dass die Update-Operation eindeutig nicht atomar ist. f2 wird zuerst geändert. f1 wird geändert, nachdem der aktualisierte Wert von f2 verwendet wurde, nicht der ursprüngliche Wert.


0
2017-12-14 23:36