![]() |
Datenbank: Firebird • Version: 2.0 • Zugriff über: IBX
Transactionen
Hallo Leute,
ich habe mich mal über IBX und Firebird belesen. Zugreifen ändern einfügen geht alles nur mit zwei oder meheren Progammen auf eine DB das will immer noch nicht so recht. Ich habe alle Ratschläge versucht umzusetzen. Aber ich komme noch nicht so recht klar. Also habe ich für jeden zugriff ob lesen, einfügen oder ändern jedes mal StartTransaction nach lesen ein Rollback nach ändern oder einfügen ein Commit. jetzt bekomme ich immer wieder die Meldung Transaction ist aktiv oder Transaction ist nicht activ obwohl direkt vor dem IBQuery ... ein StartTransaction steht. Ich benutze keine Datasource, ich lade alles in listen und lasse es über Listview anzeigen.
Delphi-Quellcode:
procedure TDM.sSql(Sql : String);
begin IBTransaction1.StartTransaction; IBSQL1.SQL.Clear; IBSQL1.SQL.Text := Sql; IBSQL1.ExecQuery; IBTransaction1.Commit; end; procedure TDM.F2Anzeige(ID : Integer); begin if not Assigned(Form2) then exit; if Form2.WindowState = wsMinimized Then exit; IBTransaction1.StartTransaction; IBQuery1.Open; IBQuery1.Locate('ID', kunden[id].id, [loCaseInsensitive]); k_ID := DM.IBQuery1ID.AsInteger; Form2.JvComboBox1.Text := DM.IBQuery1ANREDE.AsString; Form2.JvEdit1.Text := DM.IBQuery1VORNAME.AsString; Form2.JvEdit2.Text := DM.IBQuery1NAME.AsString; Form2.JvComboBox2.Text := DM.IBQuery1LAND.AsString; Form2.JvEdit3.Text := DM.IBQuery1PLZ.AsString; Form2.JvEdit4.Text := DM.IBQuery1ORT.AsString; Form2.JvEdit5.Text := DM.IBQuery1STRASSE.AsString; Form2.JvEdit6.Text := DM.IBQuery1TEL.AsString; Form2.JvEdit7.Text := DM.IBQuery1FAX.AsString; Form2.JvEdit8.Text := DM.IBQuery1MAIL.AsString; Form2.JvEdit9.Text := DM.IBQuery1KNR.AsString; IBQuery1.Close; IBTransaction1.Rollback; end; function TDM.Kundeneu : integer; begin IBTransaction1.StartTransaction; Abfrage.Close; Abfrage.SQL.Clear; Abfrage.SQL.Add('SELECT * FROM KUNDEN ORDER BY CAST(KNR AS INTEGER) ASC'); Abfrage.Open; Abfrage.Last; Result := Abfrage.FieldByName('KNR').AsInteger + 1; IBTransaction1.Rollback; end; procedure TDM.DKunden(SQL : String); var a : integer; itm : TListItem; begin IBTransaction1.StartTransaction; if SQL <> '' Then begin IBQuery1.Close; IBQuery1.SQL.Clear; IBQuery1.SQL.Add(sql); end; IBQuery1.Open; SetLength(Kunden, 1); IBQuery1.First; While not IBQuery1.Eof do begin setlength(kunden, length(kunden)+1); a := length(kunden)-1; kunden[a].id := IBQuery1ID.AsInteger; kunden[a].knr := IBQuery1KNR.AsInteger; kunden[a].name := IBQuery1NAME.AsString; kunden[a].vorname := IBQuery1VORNAME.AsString; IBQuery1.Next; end; IBQuery1.Close; IBTransaction1.Rollback; end; procedure TDM.AKunden(ListView : TJvListView); var a : integer; itm: TListItem; begin ListView.Items.Clear; for a := 1 to Length(kunden)-1 do begin itm := ListView.Items.Add; itm.Caption := IntToStr(kunden[a].id); itm.SubItems.Add(kunden[a].vorname); itm.SubItems.Add(kunden[a].name); end; ListView.Items[ListView.Items.Count-1].MakeVisible(True); if a < 0 then ListView.ItemIndex := ListView.Items.Count-1 else ListView.ItemIndex := a; F2Anzeige(a); unit3.KuNr := IntToStr(kunden[a].knr); unit4.KuNr := IntToStr(kunden[a].knr); end; |
Re: Transactionen
Zitat:
Mir fällt auserdem auf, dass du dein Datenmodul und das Formular auf sehr ungünstige Weise vermischt. In procedure TDM.F2Anzeige(ID : Integer) kennt das Datenmodul das Formular (das ist schlecht) und das Fomular kennt das Datenmodul (das ist in Ordnung). Ehrlich gesagt ist die Procedure eine einzige Katastrophe. Nicht mal das Ergebnis von Locate wird überprüft. Wenn du z.B. TForm2.JvEdit5 einen sinnvollen Namen geben möchtest, musst du gleich an zwei Stellen ändern. Ich schlage vor, TDatasource und TEdit Objekte zu benützen. Dadurch wird die Kopplung zwischen Formular und Datenmodul automatisch verringert und ausserdem ist Funktionalität für die du stundenlang programmieren müsstest schon vorhanden. Um eine neue Kundennummer zu ermitteln, brauchst du nicht alle Daten abrufen und diese dann auch noch sortieren.
Delphi-Quellcode:
Ansonsten würde ich keinerlei Transactions benützen, sondern alles
function TDM.Kundeneu : integer;
begin Abfrage.SQL.Add('SELECT MAX(KNR)+1 FROM KUNDEN'); Abfrage.Open; result := Abfrage.Fields[0].AsInteger; Abfrage.Close; end; ![]() Transactions werden erst dann wichtig, wenn z.B. mehrere Arbeitsstationen auf die gleichen Daten zugreifen oder Änderungen an mehreren Tabellen ganz oder gar nicht vorgenommen werden müssen. |
Re: Transactionen
Eine neue Kundennummer sollte aber über einen Generator plus GenID() erfolgen
|
Re: Transactionen
Ich möchte ja grundsätzlich verstehen wie das mit mehrern anwendungen auf eine datenbank ist. die Datasource habe ich weggelassen da die Transaction sonst offen bleiben muß und eine Andere Anwendung nicht die daten bearbeiten kann.
|
Re: Transactionen
Hallo,
jeder hat mal angefangen, also nicht immer gleich losschreien ;) Zitat:
Irgendwo wird die Transaktion doch nicht geschlossen Dein Code
Delphi-Quellcode:
procedure TDM.sSql(Sql : String);
begin IBTransaction1.StartTransaction; IBSQL1.SQL.Clear; IBSQL1.SQL.Text := Sql; IBSQL1.ExecQuery; IBTransaction1.Commit; end; Mein Code:
Delphi-Quellcode:
Das begin/end beim Commit erlaubt es übrigens,
procedure TDM.sSql(Sql : String);
begin IBTransaction1.StartTransaction; try try IBSQL1.SQL.Clear; IBSQL1.SQL.Text := Sql; IBSQL1.ExecQuery; except IBTransaction1.RollBack; end; finally if IBTransaction1.InTransaction then begin IBTransaction1.Commit; end; end; end; einen Breakpoint zu setzen (bei der Fehlersuche ganz hilfreich) Nutze als try/except, try/finally wie ich. Eine letzte Sache, die DataBases/Transaktionen sollten nicht im Object-Inspector geöffnet/aktiv gesetzt werden. Heiko |
Re: Transactionen
Hallo Heiko,
das hat mich ein ganze Stück weiter gebracht, Danke. Aber nur mal so am Rande : Ist es überhaupt möglich wenn man TDatasource verwendet "gleichteitige" zugriffe auf eine DB mit IBX oder ZEOS. Es ist ja immer geöffnet wenn man DBGrid auch noch hat und die Daten permanet angezeigt werden? |
Re: Transactionen
Du mustt die datenmengen halt entsprechend auffrischen (.Refresh). Z.B. durch Events
|
Re: Transactionen
Hallo,
oder ein TClientDataSet für die DBGrid-Anzeige verwenden. Ich persönlich benutze DBGrid gar nicht, sondern ein normales StringGrid. Heiko |
Re: Transactionen
Ich verwende sehr gerne ListView weil es den Inhalt nur verdeckt wenn er für dei zelle zugroß ist und wenn man mit der maus darüber geht zeigt er den rest in Hit ohne eine zeile code.
|
Alle Zeitangaben in WEZ +1. Es ist jetzt 14:54 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-2025 by Thomas Breitkreuz