Ich habe eine Delphi-Anwendung gemacht, die eine Zeile in Firebird-Datenbank einfügt. Es gab ein Problem mit einer Abfrage, die über CommitRetaining gelöst wurde, aber ich habe gelesen, dass es nicht richtig ist zu verwenden, weil es den Server möglicherweise langsamer beeinflussen kann. Seltsames passiert, wenn ich nur Commit verwende, Abfrage läuft in Ordnung, aber wenn ich sehen will, ob die Zeile eingefügt ist, ist Retainingit nicht. Es wird nur beim Beenden der Anwendung eingefügt. Bei der Verwendung von CommitRetaining wird die Zeile jedoch sofort eingefügt.Commit vs CommitRetaining
Was kann das Problem verursachen? EDIT: Code CommitRetaining mit
adqPom := TADQuery.Create(nil);
adqPom.Connection := form1.ADOConnection1;
adTransakcija := TADTransaction.Create(nil);
adTransakcija.Connection:=form1.ADOConnection1;
adqPom.Transaction:=adTransakcija;
adTransakcija.StartTransaction;
try
with adqPom do
begin
close;
sql.Clear;
sql.Add('insert into uplate(sifra,b_prijema,magacin,datum,iznos,b_uplate,b_izvoda,banka,godina,tr_rac,datum_dokument)');
sql.Add('values(:S,:BP,:M,:D,:I,:BU,:BI,:B,:G,:TR,:DD)');
ParamByName('S').Value := strtoint(edit1.Text);
if Form15.adoqDostavn.FieldValues['A1'] = 3 then
edit3.Text := '99999';
ParamByName('BP').Value := edit3.Text;
ParamByName('M').Value := edit2.Text;
ParamByName('D').Value := strtodate(edit4.Text);
ParamByName('I').Value := StrToFloat(edit5.Text);
ParamByName('BU').Value := Br_Uplate+1;
ParamByName('BI').Value := strtoint(Edit6.Text);
ParamByName('B').Value := Edit8.Text;
ParamByName('G').Value := 2006;
if Form15.adoqDostavn.FieldValues['A1'] = 3 then
ParamByName('TR').Value:= form15.adoqDostavn.FieldValues['B_PRIJEMA']
else
ParamByName('TR').Value:= Form15.adoqDostavn.FieldValues['B_DOST'];
ParamByName('DD').Value:=StrToDate(edit9.Text);
ExecSQL;
end;
adTransakcija.CommitRetaining;
except
adTransakcija.RollbackRetaining;
raise;
end;
FreeAndNil(adTransakcija);
FreeAndNil(adqPom);
EDIT: Code Commit mit (eigentlich Eigenschaft einer Abfrage Autocommit gesetzt)
adqPom := TADQuery.Create(nil);
adqPom.Connection := form1.ADOConnection1;
with adqPom do
begin
close;
sql.Clear;
sql.Add('insert into uplate(sifra,b_prijema,magacin,datum,iznos,b_uplate,b_izvoda,banka,godina,tr_rac,datum_dokument)');
sql.Add('values(:S,:BP,:M,:D,:I,:BU,:BI,:B,:G,:TR,:DD)');
ParamByName('S').Value := strtoint(edit1.Text);
if Form15.adoqDostavn.FieldValues['A1'] = 3 then
edit3.Text := '99999';
ParamByName('BP').Value := edit3.Text;
ParamByName('M').Value := edit2.Text;
ParamByName('D').Value := strtodate(edit4.Text);
ParamByName('I').Value := StrToFloat(edit5.Text);
ParamByName('BU').Value := Br_Uplate+1;
ParamByName('BI').Value := strtoint(Edit6.Text);
ParamByName('B').Value := Edit8.Text;
ParamByName('G').Value := 2006;
if Form15.adoqDostavn.FieldValues['A1'] = 3 then
ParamByName('TR').Value:= form15.adoqDostavn.FieldValues['B_PRIJEMA']
else
ParamByName('TR').Value:= Form15.adoqDostavn.FieldValues['B_DOST'];
ParamByName('DD').Value:=StrToDate(edit9.Text);
ExecSQL;
end;
FreeAndNil(adqPom);
Ich könnte falsch liegen, aber der einzige Unterschied, den ich kenne, ist, dass CommitRetaining die Transaktion nur im aktiven Zustand behalten sollte. Wo hast du gelesen, dass CommitRetaining keine gute Praxis ist? Versuchen Sie, die Transaktion nach einem "normalen" Commit zu reaktivieren, Sie sollten die Zeilen finden, die Sie eingefügt haben. – ExDev
@ExDev Commit beibehalten ** kann ** problematisch sein, weil die Transaktionslücke erhöht, wenn die Transaktion zu lange am Leben ist, was verhindert, Garbage Collection, die zu längeren Datensatz Versionsketten führen kann, die gescannt werden müssen, was dann führen kann schlechtere Leistung. –
Klingt so, als ob Sie eine Transaktion abfragen, die vor dem Einfügen des Datensatzes gestartet wurde. Sie müssen den Code anzeigen, der dieses Problem aufweist. –