![]() |
Datenbank: Firebirdd • Version: 3 • Zugriff über: Seattle
To Commit or not to commit
Hallo,
das man in einer echten Datenbank (Firebird) z. B. einen Datensatz nicht einfach nur einfügt sondern das ganze noch commiten muss, ist mir klar. Nun stellte ich aber gerade fest, dass ein Commit das ich abgesetzt habe, überhaupt nichts brachte. Ich hatte es einfach mal auskommentiert und trotzdem sind alle Tabellen die ich gefüllt habe ordnungsgemäß aufgefüllt worden. Auch ein paar "ALTER SEQUENCE "%s" RESTART WITH %d" die ich noch abgesetzt habe sind alle in der Datenbank angekommen. Nun frage ich mich, durch welchen Mechanismus ist das passiert? Ich verwende eine TFDConnection-Komponente (namens "dbsAM_FB") und eine TFDTransaction-Komponente. In dieser ist das Options.AutCommit auf "False" gesetzt. Zum Einfügen der Datensätze verwende ich einen TFDQuery. Datensätze füge ich ein mit "qry_FB.ExecSQL(InsertSQL);". Was bewirkt denn nun, dass ohne explizites "dbsAM_FB.Commit;" die Operationen (Einfügen und ALTER SEQUENCE) überhaupt nachhaltig sind? Mal der etwas verkürzte Code, der die Daten per INSERT einträgt:
Delphi-Quellcode:
Danke im Voraus. Gruß, Markus
tbl_Pdx.TableName := TableNames[i];
tbl_Pdx.Open; try try tbl_Pdx.First; InsertFieldNames := ''; InsertFieldValues := ''; qry_FB.SQL.Clear; { Zuerst sammeln wir die Felder für das Insert-Statement. } for k := 0 to Pred(tbl_Pdx.Fields.Count) do begin FieldNameUpper := RenamedField(TableName, tbl_Pdx.Fields[k].FieldName); if FieldNameUpper <> '' then begin InsertFieldNames := InsertFieldNames + Format('"%s", ', [FieldNameUpper]); InsertFieldValues := InsertFieldValues + Format(':%s, ', [FieldNameUpper]); FieldNames[k] := FieldNameUpper; end else begin FieldNames[k] := ''; end; end; InsertFieldNames := Copy(InsertFieldNames, 1, Length(InsertFieldNames)-2); InsertFieldValues := Copy(InsertFieldValues, 1, Length(InsertFieldValues)-2); InsertSQL := Format('INSERT INTO "%s" (%s) VALUES (%s)', [TableName, InsertFieldNames, InsertFieldValues]); qry_FB.SQL.Add(InsertSQL); { Jetzt sammeln wir die Felder für das "Params". } for k := 0 to Pred(tbl_Pdx.Fields.Count) do begin FieldNameUpper := tbl_Pdx.Fields[k].FieldName; if FieldNameUpper <> '' then begin FieldNameUpper := tbl_Pdx.Fields[k].FieldName; qry_FB.Params.CreateParam(tbl_Pdx.Fields[k].DataType, FieldNameUpper, ptInput); end; end; { Alle Datensätze der Quelltabelle durchlaufen. } for j := 0 to Pred(RecordCount) do begin FMeter.CurrentValue := Succ(j); Percent := (100 * j) div RecordCount; for k := 0 to Pred(tbl_Pdx.Fields.Count) do begin if FieldNames[k] = '' then Continue; // Ein Feld das in der Zieltabelle nicht mehr vorhanden ist überspringen FieldNameMixed := tbl_Pdx.Fields[k].FieldName; FieldNameUpper := FieldNames[k]; { Nun die Werte je nach Datentyp übertragen von der Quelle ins Ziel } case tbl_Pdx.Fields[k].DataType of ftString : if FieldNameMixed <> 'LoginPassword' then begin qry_FB.ParamByName(FieldNameUpper).AsString := tbl_Pdx.FieldByName(FieldNameMixed).AsString; end else begin qry_FB.ParamByName(FieldNameUpper).AsString := GetStrHashBobJenkins(tbl_Pdx.FieldByName(FieldNameMixed).AsString); end; end; // case tbl_Pdx.Fields[k].DataType of end; // for k := 0 to Pred(tbl_Pdx.Fields.Count) do { Wenn nur simuliert werden soll, keine Daten eintragen. } if not chkSimulation.Checked then qry_FB.ExecSQL(InsertSQL); tbl_Pdx.Next; { Daten nur in größeren Brocken an die Datenbank übertragen. } if (j mod 5000) = 0 then begin if not chkSimulation.Checked then dbsAM_FB.Commit; end; end; // for j := 0 to Pred(tbl_Pdx.RecordCount) do if FStoped then Break; // Bricht die komplette Konvertierung sofort ab FSkip := False; finally tbl_Pdx.Close; end; |
AW: To Commit or not to commit
Die Queries haben noch ne Property AutoCommit die standardmäßig auf true steht
|
AW: To Commit or not to commit
Zitat:
Delphi-Quellcode:
Das Property "UpdateUptions.AutoCommitUpdates" steht also noch auf dem Defaultwert "False".
object qry_FB: TFDQuery
Connection = dbsAM_FB Left = 497 Top = 609 end Allerdings entdecke ich gerade, dass das Property "Transaction" der Query nicht gesetzt ist. Das sollte man sicherlich tun. |
AW: To Commit or not to commit
Zitat:
![]() Wieder was gelernt. |
AW: To Commit or not to commit
Übrigens: DDL braucht im Gegensatz zu DML kein Commit. Kurz und vereinfacht gesagt: Alles was die Struktur ändert kann ohnehin nicht Rückgängig gemacht werden, demzufolge spart man sich die Commits. Und ein Alter irgendwas ändert die Struktur...
Sherlock |
AW: To Commit or not to commit
Zitat:
|
AW: To Commit or not to commit
Zitat:
Oracle hat auch einen "Abfalleimer" für gelöschte Tabellen. Wenn man sich wundert das die Datenbank nicht kleiner wird sollte man die Tabellen im "Abfalleimer" entgültig löschen. |
AW: To Commit or not to commit
Zitat:
Delphi-Quellcode:
Nun habe ich auch um das ganze ALTER SEQUENCE Gedöns eine Transaction gestartet und dann klappt es wieder.
226: 08.09.2016 13:16:33: Error: @@@
Modul: [FireDAC][Phys][FB]Dynamic SQL Error SQL error code = -901 invalid transaction handle (expecting explicit transaction start) ErrorId: 1008 Msg: TfrmAMU.ClearTables: Table: [TA_AssetBlock] Error: [FireDAC][Phys][FB]Dynamic SQL Error SQL error code = -901 invalid transaction handle (expecting explicit transaction start) |
AW: To Commit or not to commit
Zitat:
Thomas |
AW: To Commit or not to commit
Zitat:
Wichtig für die Arbeit mit Systemen, die sich wie Oracle verhalten, ist vielleicht im Einzelfall bei DDL ohne Autocommit: DDL macht eigenständig ein Commit, man kann es nicht verhindern, deswegen "braucht" es kein DDL. Ignoriert man das, führt es leicht zu nicht gewollten Daten-Commits. |
Alle Zeitangaben in WEZ +1. Es ist jetzt 00:58 Uhr. |
Powered by vBulletin® Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.
LinkBacks Enabled by vBSEO © 2011, Crawlability, Inc.
Delphi-PRAXiS (c) 2002 - 2023 by Daniel R. Wolf, 2024 by Thomas Breitkreuz