2017-05-08 3 views
2

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); 
+0

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

+1

@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. –

+0

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. –

Antwort

1

frei, die Transaktionsumgebung Commit und CommitRetaining a Commit, dass nicht die freie Transaktionsumgebung (Cursor sind noch geöffnet). Sie können CommitRetaining in einem Prozess verwenden, aber am Ende müssen Sie Commit verwenden, um den Speicher freizugeben.

Normalerweise CommitRetainning wird verwendet, um einen Prozess zu optimieren (die eine große Anzahl von Begin/Commit enthalten), aber am Ende von Ihnen muss dieser Prozess Commit verwenden, um Speicher zu löschen.

Verwandte Themen