[MySQL 5.1.16] INSERT mit Bedingung


  • Administrator

    Grüsse zusammen,

    Ich habe ein kleines Problem. Daten werden auf Räume verteilt. Der Admin soll diese Räume erstellen und pro Raum, kann nur eine bestimmte Anzahl an Daten vorhanden sein.

    Es gibt somit eine Tabelle mit Daten und eine mit den Räumen.

    Bei der Eingabe neuer Daten, so soll einer der Räume ausgewählt werden mit noch freien Plätzen und wenn möglich dem kleinsten Index.
    Danach sollen die Daten eben in in die Datentabelle eingetragen werden mit dem entsprechenden Raum.

    Das erste ist somit eine SELECT Anfrage, welche den Raum zurückliefernt, und das zweite ein INSERT INTO. Problem ist, dass sich das Resultat von der SELECT Anfrage ändert, mit dem INSERT INTO.

    Wenn jetzt zum Beispiel nur noch einen einzigen Datensatz Platz hat in einem Raum und zwei Skripte ihren Datensatz einfügen wollen. Dann führen zum Beispiel beide zuerst die SELECT Anfrage aus, erhalten den Raum wo es noch einen Platz hat und fügen beide ihren Datensatz dort ein, wodurch es nun einen Überlauf gegeben hat. Wie kann ich das verhindern? Wie kann ich es erreichen, dass die Queries hintereinander ausgeführt werden?

    Vielen Dank für die Hilfe.

    Grüssli



  • Wenn es nicht Datenbankunabhaengig sein muss wuerde ich in deinem Fall einfach einen Trigger verwenden und dort das einfuegen verbieten wenn kein Platz mehr ist. Idealerweise natuerlich einen before insert-Trigger. 🤡


  • Administrator

    Ajaw schrieb:

    Wenn es nicht Datenbankunabhaengig sein muss wuerde ich in deinem Fall einfach einen Trigger verwenden und dort das einfuegen verbieten wenn kein Platz mehr ist. Idealerweise natuerlich einen before insert-Trigger. 🤡

    *sigh* ... *hasst diese Trigger Dinger* ^^
    Wie gingen die schon wieder? Meine Datenbankvorlesung ist etwas her und im MySQL Handbuch finde ich gerade nichts dazu, wie man die ganze Aktion stoppen kann, nur wie man andere Veränderungen zur gleichen Zeit vornimmt.
    Zudem weiss ich noch nicht ob ich SUPER Rechte habe, bei der Datenbank, was ich aber bei der MySQL Version 5.1.16 brauche um einen Trigger erstellen zu können.

    Und anders gesagt, müsste ich zuerst den Raum holen, dann insert into ausführen, welcher der Trigger auslöst, dort wird erneut ein Select ausgeführt, welches überprüfen soll ob es noch Platz hat? Kann es dann nicht sein, dass die SELECT Anfrage im Trigger wieder nicht synchronisiert mit der anderen Anfrage passieren kann und ich somit gleich weit bin, nur mit einem Trigger und einer Select Anfrage zusätzlich?

    Noch eine Frage:
    Ist eigentlich garantiert, dass immer nur ein Query zur gleichen Zeit ausgeführt wird? Also wenn ich die INSERT INTO Operation in ein Query mit mehreren SELECT Anweisung einfügen könnte (Bsp: INSERT INTO t SELECT x, y, z FROM f WHERE (SELECT MIN(u) FROM i WHERE k = 0) NOT NULL), wäre dann garantiert, dass diese gesamte Anweisung zu ende ausgeführt wird, bevor irgendeine andere Anweisung startet?

    Grüssli



  • im normalfall schon, weil bei einer transaktion die datenbank (-tabelle) gelocked wird soweit ich weiß



  • Dravere schrieb:

    Kann es dann nicht sein, dass die SELECT Anfrage im Trigger wieder nicht synchronisiert mit der anderen Anfrage passieren kann und ich somit gleich weit bin, nur mit einem Trigger und einer Select Anfrage zusätzlich?

    Du hast Recht. Ich habe das wohl nicht zu Ende gedacht. 😮

    Ist eigentlich garantiert, dass immer nur ein Query zur gleichen Zeit ausgeführt wird? Also wenn ich die INSERT INTO Operation in ein Query mit mehreren SELECT Anweisung einfügen könnte (Bsp: INSERT INTO t SELECT x, y, z FROM f WHERE (SELECT MIN(u) FROM i WHERE k = 0) NOT NULL), wäre dann garantiert, dass diese gesamte Anweisung zu ende ausgeführt wird, bevor irgendeine andere Anweisung startet?
    Grüssli

    Nein. Das kann man so pauschal nicht sagen. Das haengt von einigen Faktoren ab.

    Was du braeuchstest waere, dass du die Transaktionsisolation auf Serializable umstellst. Da sorgt die Datenbank dann quasi selbst fuer die serielle Ausfuehrung deiner Transaktionen, bzw. simuliert diese zumindest. Ob MySQL das unterstuetzt kann ich dir allerdings nicht sagen, dazu hab ich zu wenig Erfahrung damit. Waere aber ein Unding wenn nicht. 🤡


Log in to reply