Delphi > FireDAC
Dvě FDConnection řízené jednou FDTransaction končí chybou
KarelHorky:
Předělávám starší projekt, kde používám komponenty IBX (IBExpress), na FireDAC, databáze jsou Firebird. Jednu funkčnost z IBX se mi nepodařilo převést a to řízení dvou FDConnection jednou společnou FDTransaction. Samotné napojení funguje, chyba se objeví až v Prepare první FDQuery, napojené na jednu z FDConnection. Přesné znění chyby: [FireDAC][Phys][FB]-343. Cannot set default transaction.
--- Kód: Delphi --- FDPhysFBDrivLink: TFDPhysFBDriverLink; FDGUIxWaitCur: TFDGUIxWaitCursor; FDConn: TFDConnection; FDTran: TFDTransaction; FDSQL: TFDQuery; DB2: TFDConnection; TB2: TFDQuery; try FDConn.Close; FDConn.Params.Clear; FDConn.Params.Add('DriverID=FB'); FDConn.Params.Add('Database=c:\a\DBJedna.fdb'); FDConn.Params.Add('Server=LOCALHOST/3050'); FDConn.Params.Add('Protocol=TCPIP'); FDConn.Params.Add('user_name=JMENO'); FDConn.Params.Add('password=heslo'); FDConn.Params.Add('lc_ctype=WIN1250'); DB2.Close; DB2.Params.Clear; DB2.Params.Add('DriverID=FB'); DB2.Params.Add('Database=c:\a\DBDva.fdb'); DB2.Params.Add('Server=LOCALHOST/3050'); DB2.Params.Add('Protocol=TCPIP'); DB2.Params.Add('user_name=JMENO'); DB2.Params.Add('password=heslo'); DB2.Params.Add('lc_ctype=WIN1250'); FDConn.Transaction := FDTran; DB2.Transaction := FDTran; FDSQL.Transaction := FDTran; TB2.Transaction := FDTran; FDConn.Open; DB2.Open; if not FDTran.Active then FDTran.StartTransaction; FDSQL.Close; FDSQL.SQL.Text := 'select count(id) from dph'; FDSQL.Prepare; { tady je chyba [FireDAC][Phys][FB]-343. Cannot set default transaction } FDSQL.Open; Log(Format('DBJedna pocet vet DPH %d',[FDSQL.Fields[0].AsInteger])); FDSQL.Close; TB2.Close; TB2.SQL.Text := 'select count(id) from dph'; TB2.Prepare; TB2.Open; Log(Format('DBDva pocet vet DPH %d',[TB2.Fields[0].AsInteger])); TB2.Close; if FDTran.Active then FDTran.Commit; except on E: Exception do begin Log(e.Message); if FDTran.Active then FDTran.Rollback; end; end; FDConn.Close; DB2.Close; Již se to tady řešilo v 2018, ale žádný výsledek to nepřineslo, viz https://forum.delphi.cz/index.php?topic=16387.0
Pokud by však od té doby někdo věděl, jak to vyřešit a používal to, byl bych mu velmi vděčný.
Díky, Karel.
pf1957:
Mozne by to podle vseho melo byt, alespon z pohledu vlastniho Firebirdu:
https://www.wisdomjobs.com/e-university/firebird-tutorial-210/multi-database-transactions-7835.html
Ale jak sdilet jednu transakci na urovni komponent me nenapada, kdyz kazda transakce ma jednu property Connection. Asi bych zkusil ta spojeni otevrit, transakci priradit connection a zahajit ji a zahajenou ji zkusit priradit k druhemu connection. A pokud to nepujde, tak bych se zeptal nekde na SO.
KarelHorky:
Ano, Firebird to podporuje, protože s komponentami IBX mi to fungovalo od Delphi 7 a roky také v Delphi XE6.
Tvůj návrh postupného přiřazení již běžící transakce jsem otestoval, ale nemá to žádný vliv, chyba je stále stejná a na stejném místě.
SO jsem prohledával a řešení nenašel, ani nikde jinde. Zkusím se zeptat přímo na SO.
Díky, Karel.
pf1957:
--- Citace: KarelHorky 23-09-2022, 12:43:20 ---Ano, Firebird to podporuje, protože s komponentami IBX mi to fungovalo od Delphi 7 a roky také v Delphi XE6.
--- Konce citace ---
A tam jsto delal jak? Jak uvadis v tom kodu?
KarelHorky:
Mám to použité ve službě a nastavil jsem to jednoduše v designtime. Na datový modul služby jsem umístil dvě komponenty TIBDatabase, jednu TIBTransaction a pár TIBSQL. Všem jsem nastavil tu jednu stejnou transakci a jede to. Nic dalšího se nemuselo nastavovat. Otevřít databáze, zahájit transakci, zadat příkazy pro select z jedné databáze, insert do druhé databáze, potom i z druhé do první, potvrdit transakci, odpojit databáze. Všechno je obaleno blokem try-except, kdyby došlo k chybě, rollbackem transakce se zruší změny v obou databázích.
Tady jsem chtěl ukázat příklad, aby tomu každý rozuměl, případně jednoduše otestoval.
Navigace
[0] Seznam témat
[#] Další strana
Přejít na plnou verzi