Open aneudecker opened 5 years ago
Ist mir auch gerade aufgefallen. Sollten wir auf jeden Fall umsetzen! Ich sehe aktuell eigentlich nur Bedarf bei truncate und evtl bei update. Bei den anderen Vorgängen wir nur eine insert infile
Abfrage abgesetzt. Bei anderen Punkten ist es mir aber vielleicht einfach noch nicht aufgefallen.
@wahani Mir ist nicht so ganz klar, an welcher Stelle wir das am besten umsetzen. Die Standard Befehle von DBI::dbBegin, DBI::dbCommit haben bei mir nicht funktioniert. Außerdem scheint es noch nötig zu sein, dass man SET autocommit = 0
auf der Datenbank setzt.
Evlt. ist es auch besser es direkt in der Query umzusetzen? Ich gebe dir das Issue mal, da es mir hier an Expertise fehlt ...
Für sendData:
Wir nutzen die sendData Befehle derzeit für den Bulk-Upload von Daten. Dabei bekommt jeder Upload eine eigene Verbindung und jeder send data local infile ist ohnehin in einer Transaktion. Für den mode truncate erübrigt sich zudem die Frage, da hierbei Schema Änderungen (drop table, create table) durchgeführt werden und es dafür keinen Rollback gibt. Wenn ich es richtig sehe wird durch eine Änderung am Schema auch automatisch ein Commit ausgelöst. Also selbst wenn es möglich wäre, müssten wir dabei sehr aufpassen, ob zwischendurch einmal ein truncate genutzt wird.
@aneudecker hat sich hier das Upload Szenario geändert und wir brauchen mehrere Schreibvorgänge in einer Transaktion / Aufruf?
Für sendQuery:
Es ist natürlich möglich Daten in einem Aufruf über sendQuery in eine DB zu schreiben, aber so ist es eigentlich nicht gedacht. Für Schreibvorgänge haben wir ja gerade die sendData Methode, insofern sehe ich auch hier noch nicht den Use-Case.
Generell ist es in unseren Anwendungen so, dass wir sehr wenige, dafür aufwändige Schreibvorgänge haben. Hier noch eine Referenz zum Daten-Laden mit load data local infile.
@aneudecker @jonathan-inwt mein Fazit wäre hierbei derzeit, dass wir keinen Bedarf dafür haben, etwas an dem Modus zu ändern für jeden Upload eine eigene Verbindung aufzubauen. Damit würden wir auch nicht davon profitieren, eine Transaktion explizit zu machen, im Vergleich zu dem impliziten Vorgehen, was wir derzeit nutzen. Bitte widersprechen, wenn ich etwas übersehen habe.
In sports-redshift haben wir transactions eingeführt, da redshift Primary Keys nicht erzwingt. Wir waren also gezwungen, in eine Staging-Tabelle zu schreiben, den PK zu prüfen und ggf. Daten aus der Zieltabelle zu löschen, bevor dann der eigentliche Schreibprozess erfolgen konnte. An dieser Stelle ist es eindeutig, da ein Fehler beim Schreiben Daten aus der Zieltabelle gelöscht, aber nicht wieder befüllt hätte.
Das Problem haben wir glücklicherweise mit MariaDB nicht.
Problematisch ist bei uns vor allem das inkonsistente Verhalten der vier Modi. Wenn wir beim Schreibvorgang einen Fehler produzieren (bspw. Duplicate entry for key 'PRIMARY
oder data truncated
), dann schreiben wir mit replace
und update
überhaupt keine Daten in die Datenbank, wohingegen bei insert
und truncate
alle Daten bis zum Fehler tatsächlich in der Datenbank landen.
Folgendes haben wir hierzu besprochen: Derzeit sind Transaktionen nicht das zentrale Thema. Wie bereits oben geschrieben, wir nutzen überwiegend Bulk-Uploads mit load data local infile und ein gemeinsamer Commit der kompletten Daten ist nicht unbedingt notwendig.
Das zentrale Problem ist allerdings, dass wir unterschiedliches Verhalten bei Fehlern unserer sendData-Modes haben:
Lösungen
Bei Funktionen, die aus mehreren SQL Befehlen bestehen, sollten wir mit Transactions arbeiten. Das betrifft insbesondere
sendData
mitmode = "truncate"
, aber evtl. auch andere Funktionen.