AGB  ·  Datenschutz  ·  Impressum  







Anmelden
Nützliche Links
Registrieren
Zurück Delphi-PRAXiS Programmierung allgemein Datenbanken Delphi Firebird:deadlock - update conflicts with concurrent update

Firebird:deadlock - update conflicts with concurrent update

Ein Thema von Gruber_Hans_12345 · begonnen am 13. Feb 2006 · letzter Beitrag vom 13. Feb 2006
Antwort Antwort
Seite 2 von 2     12
Benutzerbild von Jasocul
Jasocul

Registriert seit: 22. Sep 2004
Ort: Delmenhorst
1.345 Beiträge
 
Delphi 11 Alexandria
 
#11

Re: Firebird:deadlock - update conflicts with concurrent upd

  Alt 13. Feb 2006, 13:27
Zitat von Hansa:
@Jasocul : wie kann ich denn leicht feststellen, ob sich ein Datensatz während der Bearbeitung von woanders her geändert hat ? Vor allem : woher weiß ich, was sich genau geändert hat um gezielt darauf zu reagieren ?
Zitat von Jasocul:
Datensatz einlesen und nicht locken (Keine DB-sensitiven Felder verwenden!).
Jetzigen DS-Inhalt merken.
Änderungen durchführen (Off-Line).
Den Datensatz aktuell nochmal holen und vergleichen, ob er sich geändert hat.
Hat sich geändert -> Daten können nicht geschrieben werden, da DS sich geändert hat.
Keine Änderung -> eigene Änderungen können gespeichert werden.
@Hansa:
Nicht immer nur einen Teil lesen.
Peter
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.428 Beiträge
 
Delphi 2007 Professional
 
#12

Re: Firebird:deadlock - update conflicts with concurrent upd

  Alt 13. Feb 2006, 13:53
So, hab mich mit den Infos noch etwas dahintergehängt, und nun folgendes zusammengestellt :

In meiner Transaction verwende ich nun folgendes als Parameter

SQL-Code:
read_committed
wait
nun verhält sich das ganze so, wie ich es möchte .... hoffe das hat keine negativen seiteneffekte
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Hansa

Registriert seit: 9. Jun 2002
Ort: Saarland
7.554 Beiträge
 
Delphi 8 Professional
 
#13

Re: Firebird:deadlock - update conflicts with concurrent upd

  Alt 13. Feb 2006, 17:41
Echt lustig, zu lesen, daß es mit dem Lesen angeblich nichts zu tun hat und read_committed den Fehler beseitigt. 8) Da sage ich nur : zu zwangsläufigen Nebenwirkungen fragen sie ihren Apotheker. Ich bleibe dabei : schreibende Ttransaktionen möglichst kurz halten und die lesende abtrennen.

Zitat von Jasocul:
Den Datensatz aktuell nochmal holen und vergleichen, ob er sich geändert hat.

Hat sich geändert -> Daten können nicht geschrieben werden, da DS sich geändert hat.

Keine Änderung -> eigene Änderungen können gespeichert werden.
[/quote]

Das ist etwas zu kurz. Wenn, dann läufts so ab : lesende Transaktion mit Commit. Der Datensatz kann dann solange offen bleiben, wie er will. Aber bevor er endgültig abgespeichert wird : Lock und neu lesen. Neu gelesenen und den vorhandenen vergleichen. Dann weiter wie Du sagst : keine Änderung : speichern, Lock aufheben.

Meine Frage zielte aber darauf hinaus einfach zu erkennen, ob ein Datensatz zwischenzeitlich doch geändert (womöglich sogar gelöscht) wurde. Was wurde wo geändert ? Speziell welche Felder sind betroffen ? Und wie darauf reagieren ? Wurden umfangreiche Änderungen von 2 Leuten durchgeführt, dann wäre es eventuell sogar sinnvoll, gezielt einen neuen Datensatz aus den 2 geänderten zusammenzubauen, bevor komplett alles über den Haufen geworfen wird. IB/FB besitzt einen BDR (Back Difference Record). Vermutlich ist der für sowas gedacht. Aber keiner weiß wie.
Gruß
Hansa
  Mit Zitat antworten Zitat
Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.428 Beiträge
 
Delphi 2007 Professional
 
#14

Re: Firebird:deadlock - update conflicts with concurrent upd

  Alt 13. Feb 2006, 17:50
Zitat von Hansa:
Echt lustig, zu lesen, daß es mit dem Lesen angeblich nichts zu tun hat und read_committed den Fehler beseitigt. 8) Da sage ich nur : zu zwangsläufigen Nebenwirkungen fragen sie ihren Apotheker. Ich bleibe dabei : schreibende Ttransaktionen möglichst kurz halten und die lesende abtrennen.
Ich kann dir mein Beispielprogramm zeigen, damit mal klar ist was ich genau meine :

Delphi-Quellcode:
function TMyDataBase.OpenSQL(sqlCmd : string = '') : TIBQuery;
begin
    Result := TIBQuery.Create(nil);
    FLastSQL := Result;
    Result.DataBase := FDB;
    Result.Transaction := TIBTransaction.Create(nil);
    Result.Transaction.Params.Add('read_committed');
    Result.Transaction.Params.Add('wait');
    Result.Transaction.DefaultDatabase := Result.DataBase;
    Result.Transaction.StartTransaction;
    if length(sqlCmd) > 0 then Result.SQL.Text := sqlCmd;
end;

// CloseSQL macht nur ein Commit in der Transaktion und gibt alles wieder frei
// ConnectDB verbindet sich zum Firebird Server


procedure TForm1.Button1Click(Sender: TObject);
begin
    D.ConnectDB('192.168.2.250:d:\interbase\data.fdb', 'SYSDBA', 'masterkey');
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
    R.ConnectDB('192.168.2.250:d:\interbase\data.fdb', 'SYSDBA', 'masterkey');
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
    sql1 := D.OpenSQL;
    sql1.SQL.Text := 'UPDATE TEMP SET BEZEICHNUNG = ''TEST'' WHERE ID = 9';
    sql1.ExecSQL;
end;

procedure TForm1.Button4Click(Sender: TObject);
begin
    sql2 := R.OpenSQL;
    sql2.SQL.Text := 'UPDATE TEMP SET STATUS = 9 WHERE ID = 9';
    sql2.ExecSQL;
end;

procedure TForm1.Button5Click(Sender: TObject);
begin
    D.CloseSQL(sql1);
end;

procedure TForm1.Button6Click(Sender: TObject);
begin
    R.CloseSQL(sql2);
end;
Programm zwei mal starten :

im ersten Programm
*) Button1 Clicken (Datenbankverbindung herstellen)
*) Button2 Clicken (Transaction aufbauen und UPDATE)

im zweiten PRogramm
*) Button1 Clicken (Datenbankverbindung herstellen)
*) Button2 Clicken (Transaction aufbauen und UPDATE)
*) Diese Programm hängt nun (und wartet auf das COMMIT oder ROLLBACK im ersten Programm)

im ersten Programm nun Button3 -> COMMIT

*) mit Standardeinstellungen kommt im zweiten Programm der obige Deadlock Fehler
*) mit den obigen Eisntellungen, wird das UPDATE richtig ausgeführt (es steht anschließend TEST und als Status 9 in der DB)



Also: Es gibt hier keine reine Lesende Transaktion.
Die schreibende kurzhalten ist schon klar, habe ich immmer versuchtm und werde ich auch, aber wenn viele User gleichzeitig arbeiten dann passiert es trotzdem zwangsläufig ....
Gruss Hans

2B or not 2B, that is FF
  Mit Zitat antworten Zitat
Themen-Optionen Thema durchsuchen
Thema durchsuchen:

Erweiterte Suche
Ansicht

Forumregeln

Es ist dir nicht erlaubt, neue Themen zu verfassen.
Es ist dir nicht erlaubt, auf Beiträge zu antworten.
Es ist dir nicht erlaubt, Anhänge hochzuladen.
Es ist dir nicht erlaubt, deine Beiträge zu bearbeiten.

BB-Code ist an.
Smileys sind an.
[IMG] Code ist an.
HTML-Code ist aus.
Trackbacks are an
Pingbacks are an
Refbacks are aus

Gehe zu:

Impressum · AGB · Datenschutz · Nach oben
Alle Zeitangaben in WEZ +1. Es ist jetzt 19:37 Uhr.
Powered by vBulletin® Copyright ©2000 - 2024, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz