Abfragen Datenbank überschneiden sich

  • Jetzt anmelden. Es dauert nur 2 Minuten und ist kostenlos!

mischu

Neues Mitglied
5 Oktober 2020
16
0
1
47
Hallo Zusammen,
ich habe das Problem , dass Datenbankabfragen nicht konsequent der Reihe nach abgearbeitet werden und sich somit überlappen.
Über einen Kanal bekomme ich Daten geschickt, welche innerhalb einer Funktion weiterverarbeitet werden. Aus dieser Funktion heraus werden die Daten in eine DB übertragen. Wenn noch nicht vorhanden, werden die Daten in die DB geschrieben, sollten diese dort vorhanden sein, aktualisiert.
In meinem konkreten Fall, habe ich in einer Spalte JSON files liegen, welche ich auslese, aktualisiere und dann wieder in die DB transferiere. Kommen nun kurz hintereinander für das gleiche JSON mehrere Aktualisierungen, so zieht die zweite Aktualisierung das gleiche JSON aus der DB wie die Erste, da die erste Aktualisierung noch nicht in der DB gespeichert wurde. Es entsteht dadurch das Problem, dass die zweite Aktualisierung mit dem gleichen JSON-Stand wie die Erste arbeitet und somit Daten der ersten Aktualisierung verloren gehen. Das zieht sich natürlich immer weiter durch...
Ich habe mit Datenbankabfragen keine Erfahrung und suche eine Möglichkeit, das alle Daten der Reihe nach abgearbeitet werden. Ich möchte keinen Time-Loop verwenden.

Über einen Denkanstoß oder noch besser, über eine Lösung wäre ich sehr dankbar! Die Funktion VerarbeitungDaten dürfte erst aufgerufen werden, wenn der "vorherige" Durchlauf beendet wurde oder einfach nicht parallel laufen. Eine Art Liste zum Abarbeiten der eingehenden Daten? Wenn ja, wie stelle ich das am einfachsten dar?

Javascript:
function AnkommendeDaten(id, data){
    VerarbeitungDaten(id, data);
}



function VerarbeitungDaten(id, data){

    // Abfrage Datenreihe vorhanden durch count
     connection.query("SELECT COUNT(id) AS count FROM test_data WHERE id = '" + id + "'", function (err, result, fields) {

        if (result[0].count === 0) {
            // Neue Datenreihe wird in DB geschrieben
            // ...

        }else{
            // Bestehender Datensatz wird aus DB gelesen
            connection.query("SELECT data FROM test_data WHERE id = '" + id + "'", function (err, result, fields) {

            // data (json) wir aktualisiert oder erweitert
            // ...

                // data (json) wird in DB transferiert
                 connection.query("UPDATE test_data SET data = '" + jsonfile + "' WHERE id = '" + id + "'", function (err, result, fields) {
                               if (err)
                                   throw err;
                 });
            });
        }
    });
}
 
Zuletzt bearbeitet:

jonas3344

Mitglied
25 Oktober 2019
68
23
8
37
Das ist node.js, oder?

Die Krux von asynchronen Operationen. Lies Dich ins Thema Promise ein. Damit kannst du genau solch ein gewünschtes Verhalten erzwingen:

 

mischu

Neues Mitglied
5 Oktober 2020
16
0
1
47
Danke für den Link!
Ja, das ist node.js. Da werde ich mich mal vertiefen. Habe es nur überflogen, sollte aber der richtige Ansatz sein!
 

mischu

Neues Mitglied
5 Oktober 2020
16
0
1
47
Mit Promises oder Async /Await kann man eine Funktion so aufbauen, dass die folgenden Abläufe warten, bis die jeweils aktuelle Ausführung beendet ist und dann geht es mit dem nächsten Schritt weiter. Wenn ich das richtig verstanden habe, wird bei Async/ Await die nächste Ausführung in eine Liste ausgelagert, welche von "oben" her abgearbeitet wird. Diese Liste wird aber erst dann abgearbeitet, wenn alle parallel laufende nicht Async / Await Dinge abgearbeitet sind. Somit alles wunderbar.
Jetzt stehe ich aber auf der Leitung bezüglich meines Problems. Bei dem oben aufgeführten Code werden über eine Schnittstelle Daten gesendet. Wann und wie viele kann ich selber nicht beeinflussen. Wie kann ich nun einen gewünschten "Stau" (Liste zum abarbeiten) aufbauen. Letztendlich soll die function VerarbeitungDaten() erst neu aufgerufen werden, wenn die vorherigen Daten verarbeitet wurden. Bei einem Promise könnte man (wenn ich es richtig verstanden habe) mit einer Variablen true / false arbeiten. Gibt es da eine elegantere Variante?
 

jonas3344

Mitglied
25 Oktober 2019
68
23
8
37
Dass die Daten von aussen und unkontrollierbar kommen verändert das Problem natürlich. Und ohne den gesamten Kontext zu haben ist es auch schwierig da einen Lösungsvorschlag zu präsentieren.

Mit alldem was ich jetzt weiss: Ich würde den Datensatz sperren bevor du etwas ausliest und ihn wieder entsperren sobald die Daten geschrieben sind. Wenn ein Request reinkommt schaust du ob der Datensatz frei ist, wenn nicht gehst du in einen Loop, der in kurzen Abständen prüft ob der Datensatz wieder frei ist und ihn dann nutzt.
Vielleicht gibts noch einen eleganteren Weg. Aber mit Promises kannst du natürlich nur asynchronen Code innerhalb eines Requests kontrollieren.

Ich weiss nicht was du für eine Datenbank benutzt aber moderne Versionen auch von MySQL und MariaDB bieten Optionen um ein JSON-Objekt direkt im Query zu verändern.
 

mischu

Neues Mitglied
5 Oktober 2020
16
0
1
47
Danke für Deine Hilfe! Ich hab jetzt einen Puffer für die eingehenden Daten. Dieser wird mit einem time loop abgearbeitet. So hab ich das "incoming" Problem gelöst. Das korrekte Schreiben der Datensätze wird durch Promise kontrolliert und sichergestellt. :-)