Hi,
ich will mit dieser Prozedur gleichzeitige Zugriffe im Netzwerk simulieren :
Delphi-Quellcode:
procedure TForm1.WriteData (Nr : integer;bez :
string);
begin
DS.Close;
DS.SelectSQL.Text := '
SELECT * FROM TESTTABLE WHERE NR='+IntToStr (Nr);
DS.Open;
if not DS.IsEmpty
then begin
DS.Edit;
DS.FieldByName('
NR').AsInteger := Nr;
DS.FieldByName('
BEZ').AsString := '
Edit ' + bez;
end
else begin
DS.Insert;
DS.FieldByName('
NR').AsInteger := Nr;
DS.FieldByName('
BEZ').AsString := '
Ins ert ' + bez;
end;
DS.Post;
end;
procedure TForm1.btn1Click(Sender: TObject);
var i,j : Integer;
anfang : TTime;
begin
anfang := now;
DB.Open;
Randomize;
for i := 1
to 2000
do begin
j := Random (2);
WriteData (j,IntToStr(10 * i));
mem1.Lines.Add(IntToStr(i) + '
Diff. : '+ TimeToStr(now-anfang)+'
'+IntToStr (j));
end;
WriteTransaction.Commit;
end;
Durch das Random (2) ist ja klar, dass es irgendwo bald krachen wird. Soll es ja auch. Nach kurzer Zeit kommt (sofern das Programm mehrfach gestartet wird) dann auch dieser Fehler :
Zitat:
EFIBInterBaseError. Meldung: 'Form1.DS.UpdateQuery:
Unsuccessful execution caused by system error that does not preclude successful execution of subsequent statements.
Lock conflict on no wait transaction.
Deadlock.
Update conflicts with concurrent update.
Ich habe 2 Transaktionen mit diesen Parametern :
TRParams (ReadTransaction) :
read
nowait
read_committed
rec_version
TRParams (WriteTransaction) :
write
nowait
concurrency
Bei Database ist ReadTransaction las DefaultTransaction und WriteTransaction als DefaultUpdateTransaction gesetzt.
Dann noch das Dataset DS. AutoCommit steht auf true. Transaction : ReadTransaction. UpdateTransAction : WriteTransaction.
Jetzt die Frage : wie behandelt man solche Fehler jetzt am besten ? Solche Fehler werden im Realeinsatz zwar eher selten auftreten, behandeln muss man sie aber trotzdem. Wie machen das andere? Sollte man die Transaction-Parameter vielleicht anders setzen ?