Einzelnen Beitrag anzeigen

Gruber_Hans_12345

Registriert seit: 14. Aug 2004
1.436 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