Zeos Komponenten --> mySQL

Arne Buchwald

Erfahrenes Mitglied
Hallo,

ich habe mein Forumsystem nun ja auf mySQL umgestellt. Als Verbindung zur Datenbank nehme ich die Zeos-Komponenten.

Kann es bei der SQL-DB auch zu Überschneidungen (incl. Datenverlust) kommen, wenn zwei oder mehr User gleichzeitig eine Handlung (Posten, Verschicken, Edtieren, etc.) vornehmen? (Vergleich "flock" in Perl)

Wofür sind die Kompos ZBatchSQL, ZUpdateSQL und mySQLTransact?

Kann es sein, dass die DB sozusagen erst "aktualisiert" werden muss, bevor ich per INSERT INTO einen neuen Datensatz anfügen kann? Hintergrund: Wenn ich per INSERT INTO einen Post erstelle (eine INSERT-INTO-SQL-Anweisung) klappt das problemlos; wenn ich jedoch einen Thread + Post erstelle (2 INSERT-INTO-SQL-Anweisung) kommt bei der zweiten ein Fehler ...

Jemand eine Idee?
 
ich benutz auch die zeos-komponenten und bin damit rundum zufrieden. allerdings kann ich dir nicht sonderlich viel zu schreibkonflikten sagen, weil ich bis jetzt noch nie auf eine multi-user-db zugegriffen hab.

aber normalerweise sollte ja schon das dbms einen datensatz sperren, der gerade geöffnet ist. den fehler musst du dann nur noch in deinem eigenen programm abfangen. oder du gehst ganz auf nummer sicher, womit wir schon bei der transact-komponente wären: benutz transaktionen. ;)

soweit ich weiss, muss die datenbank nicht aktualisiert werden, weil die verbindung zur datenbank ja weiterhin besteht und änderungen normalerweise sofort erkannt werden sollten. sicher bin ich dabei allerdings nicht, von daher würde ich schon sagen, dass es sicherer ist, vor jedem post die db zu synchronisieren.
 
Guten Abend,

Original geschrieben von asphyxia
oder du gehst ganz auf nummer sicher, womit wir schon bei der transact-komponente wären: benutz transaktionen. ;)
Wofür sind die bzw. wie funktionieren die? Habe absolut keinen Schimmer von der Kompo.

Hast du eine Idee, woran das liegen könnte, dass er die Procedure mit EINER Sql-Insert-Into-Anweidung schluckt und die mit ZWEI nicht? Syntax, etc. ist richtig.
 
transaktionen arbeiten nach dem prinzip "ganz oder gar nicht". kleines beispiel dazu:

stell dir vor, irgendjemand überweist 1000 euro von konto a nach konto b. die eigentliche überweisung besteht dabei ja aus mehreren schritten:
1. abbuchen von konto a
2. irgendwelche zwischenschritte
3. gutschreiben auf konto b

wenn bei einem dieser schritte ein fehler auftritt, kann es passieren, dass 1000 euro von konto a abgebucht worden sind, aber nie auf konto b ankommen.
um das zu umgehen, startet man eine transaktion (mit der BeginTrans-methode) und kann bei eventuellen fehlern alle änderungen wieder rückgängig machen (mit der RollBack-methode). also werden entweder alle änderungen an irgendwelchen tabellen vorgenommen oder gar keine.

wie sieht die procedure mit den queries denn aus? darf ich mal sehen, was da nicht funktioniert?
 
Hallo,
Original geschrieben von asphyxia
transaktionen arbeiten nach dem prinzip "ganz oder gar nicht". kleines beispiel dazu:
stell dir vor, irgendjemand überweist 1000 euro von konto a nach konto b. die eigentliche überweisung besteht dabei ja aus mehreren schritten:
1. abbuchen von konto a
2. irgendwelche zwischenschritte
3. gutschreiben auf konto b

wenn bei einem dieser schritte ein fehler auftritt, kann es passieren, dass 1000 euro von konto a abgebucht worden sind, aber nie auf konto b ankommen.
um das zu umgehen, startet man eine transaktion (mit der BeginTrans-methode) und kann bei eventuellen fehlern alle änderungen wieder rückgängig machen (mit der RollBack-methode). also werden entweder alle änderungen an irgendwelchen tabellen vorgenommen oder gar keine.
Ah, verstehe - danke! Wenn sonst keine Probleme mit der Multi-User-Domain auftreten, werde ich das aber erst in Version 2.x einbauen.


wie sieht die procedure mit den queries denn aus? darf ich mal sehen, was da nicht funktioniert?
Code:
try
    MySqlQuery.Active := False;
    MySqlQuery.SQL.Clear;
    MySqlQuery.SQL.Add('INSERT INTO post VALUES (' + IntToStr(last_id) + ',' + tid + ',' + uid + ',' + QuotedStr(msg_icon) + ',' + QuotedStr(FormatDateTime('yyyy-mm-dd', StrToDateTime(DateToStr(Date)))) + ',' + QuotedStr(TimeToStr(Time)) + ',' + QuotedStr(Request.RemoteAddr) + ',' + QuotedStr(postmessage) + ')');
    MySqlQuery.ExecSQL;
  except
    nt_postmessage := 'Fehler beim Anfügen des neuen Datensatzes in der Post-Datenbank!';
    nt_topic := 'Fehler';
    Error.HTMLFile := Templatedir + '\message.html';
    bsforumtemplate := error.Content;
    title := 'Fehler';
    pp_bsforumtemplate.HTMLFile := Templatedir + '\bsforumtemplate.html';
    Response.Content := pp_bsforumtemplate.Content;
    exit;
  end;
funktioniert.

Funktioniert nicht (Untenstehendes ist die zweite Insert-Into-Anweisung):
Code:
  try
    MySqlQuery.Active := False;
    MySqlQuery.SQL.Clear;
    MySqlQuery.SQL.Add('INSERT INTO post VALUES (' + IntToStr(last_post_id) + ',' + IntToStr(postid) + ',' + uid + ',' + QuotedStr(msg_icon) + ',' + QuotedStr(FormatDateTime('yyyy-mm-dd', StrToDateTime(DateToStr(Date)))) + ',' + QuotedStr(TimeToStr(Time)) + ',' + QuotedStr(Request.RemoteAddr) + ',' + QuotedStr(postmessage) + ')');
    MySqlQuery.ExecSQL;
  except
    nt_postmessage := 'Fehler beim Anfügen des neuen Posts in der Post-Datenbank!';
    nt_topic := 'Fehler';
    Error.HTMLFile := Templatedir + '\message.html';
    bsforumtemplate := error.Content;
    title := 'Fehler';
    pp_bsforumtemplate.HTMLFile := Templatedir + '\bsforumtemplate.html';
    Response.Content := pp_bsforumtemplate.Content;
    exit;
  end;
Die Variablen haben jeweils die richtigen Werte - habe ich von Hand überprüft. Ich würde jetzt darauf tippen, dass er eine zweite Insert-Into-Anweisung nicht mag, ohne, dass davor irgendetwas noch gemacht (abgeschlossen?) wurde ... !?
 
Zuletzt bearbeitet:
sehr merkwürdig.
welche fehlermeldung gibt das programm denn zurück?

das einzige, was ich da anders machen würde, wäre statt ExecSQL die Open-methode zu nehmen, aber das ist geschmackssache. und daran kann das auch eigentlich nicht liegen.

was passiert denn, wenn du nur die zweite abfrage ausführst? bzw. wenn du die abfrage direkt an die db schickst?


eine andere möglichkeit wäre es dann noch, dass du auf die query-objekte verzichtest, und normale tables nimmst. die machen zwar intern fast das gleiche, aber da kannst du eine ganze tabelle auswählen und mit den entsprechenden methoden datensätze bearbeiten (ohne abfragen).
 
Zuletzt bearbeitet:
:( :( :( - ich blicke gar nix mehr.

Nachdem ich die erste SQL-Insert... ausgeklammert hatte, wurde der Post-Datensatz korrekt angefügt.
Jetzt, wo die Klammern wieder weg sind, kommt wieder die Fehlermeldung aus dem try ... except-Block ....
 
das ist echt komisch. und die daten bleiben nachher auch in der tabelle stehen?
sonst lad dir doch einfach mal ein recordset in die MySqlQuery (mit SELECT) und bearbeite das. wenn das bei der post-methode (oder noch eher) schon nicht mehr mitmacht, dann weiss ich auch nicht. :(

ich werd morgen mal sehen, ob ich das problem bei mir reproduzieren kann und meld mich dann nochmal.
 
Original geschrieben von asphyxia
das ist echt komisch. und die daten bleiben nachher auch in der tabelle stehen?
Ja, die Daten werden gespeichert und sind weiterhin vorhanden.


sonst lad dir doch einfach mal ein recordset in die MySqlQuery (mit SELECT) und bearbeite das. wenn das bei der post-methode (oder noch eher) schon nicht mehr mitmacht, dann weiss ich auch nicht. :(
Werde ich gleich mal machen.


ich werd morgen mal sehen, ob ich das problem bei mir reproduzieren kann und meld mich dann nochmal.
Danke.

[edit]
Ich verstehe nun gar nichts mehr. Hatten eben eine ganze Zeit nichts mehr an der DB gemacht, die dann wohl durch ein TimeOut geschlossen wurde.
Eben gerade hatte ich es dann noch einmal probiert (beide Insert-SQL-Anweisungen) und es ging !?!?!
Den Quellcode habe ich jedoch kein bisschen verändert.
Hängt das evtl. doch mit der Verbindung zur DB zusammen ???
[/edit]
 
Zuletzt bearbeitet:

Neue Beiträge

Zurück