Autor Téma: Společná FDTransaction pro více FDConnection  (Přečteno 572 krát)

Offline jd

  • Nováček
  • *
  • Příspěvků: 13
  • Karma: 0
    • Verze Delphi: D6, XE6, Berlin
Je možné sdílet FDTransaction pro více FDConnection?.
V FDConnection.Transaction a FDQuery.Transaction nastavím společnou FDTransaction.
První FDQuery.ExecSQL končí chybou [FireDac][Phys][FB]-343 Cannot set default transaction.
Pro více IBDatabase takovéto sdílení IBTransaction jde použít.
Děkuji

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3565
  • Karma: 35
    • Verze Delphi: XE7 professional
Re:Společná FDTransaction pro více FDConnection
« Odpověď #1 kdy: 23-10-2018, 11:28:18 »
Áno, bez problémov. Chyba bude niekde inde.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline jd

  • Nováček
  • *
  • Příspěvků: 13
  • Karma: 0
    • Verze Delphi: D6, XE6, Berlin
Re:Společná FDTransaction pro více FDConnection
« Odpověď #2 kdy: 23-10-2018, 14:42:10 »
Kde tedy bude chyba. Vytvoril jsem dva priklady. Button1Click je pro nesdilene FDTransaction. To projde. Button2Click je se sdilenou FDTransaction a tam to nad FDQuery1.ExecSQL skonci chybou [FireDac][Phys][FB]-343 Cannot set default transaction. Predem dekuji na nalezeni chyby. Zkouseno v Delphi 10.1

Kód: Delphi [Vybrat]
  1. procedure TForm1.Button1Click(Sender: TObject);
  2. var
  3.   FDConnection1, FDConnection2: TFDConnection; FDTransaction1, FDTransaction2: TFDTransaction; FDQuery1, FDQuery2: TFDQuery;
  4. begin try
  5.   FDConnection1 := nil; FDConnection2 := nil; FDTransaction1 := nil; FDTransaction2 := nil; FDQuery1 := nil; FDQuery2 := nil;
  6.   //
  7.   FDConnection1 := TFDConnection.Create(Self);
  8.   FDConnection1.Params.Add('Database=d:\Data5\HBACKUP\TEST\HM.kfb');
  9.   FDConnection1.Params.Add('User_Name=sysdba');
  10.   FDConnection1.Params.Add('Password=masterkey');
  11.   FDConnection1.Params.Add('DriverID=FB');
  12.   FDConnection1.LoginPrompt := FALSE;
  13.   FDTransaction1 := TFDTransaction.Create(Self);
  14.   FDTransaction1.Options.AutoCommit := FALSE;
  15.   FDTransaction1.Options.DisconnectAction := xdRollback;
  16.   FDConnection1.Transaction := FDTransaction1;
  17.   FDConnection1.Connected := TRUE;
  18.   //
  19.   FDConnection2 := TFDConnection.Create(Self);
  20.   FDConnection2.Params.Add('Database=d:\Data5\HBACKUP\TEST\HM2.kfb');
  21.   FDConnection2.Params.Add('User_Name=sysdba');
  22.   FDConnection2.Params.Add('Password=masterkey');
  23.   FDConnection2.Params.Add('DriverID=FB');
  24.   FDConnection2.LoginPrompt := FALSE;
  25.   FDTransaction2 := TFDTransaction.Create(Self);
  26.   FDTransaction2.Options.AutoCommit := FALSE;
  27.   FDTransaction2.Options.DisconnectAction := xdRollback;
  28.   FDConnection2.Transaction := FDTransaction2;
  29.   FDConnection2.Connected := TRUE;
  30.   //
  31.   FDTransaction1.StartTransaction;
  32.   FDQuery1 := TFDQuery.Create(Self);
  33.   FDQuery1.Connection := FDConnection1;
  34.   FDQuery1.Transaction := FDTransaction1;
  35.   FDQuery1.SQL.Text := 'insert into k$attachment (id) values(500)';
  36.   FDQuery1.ExecSQL;
  37.   FDTransaction2.StartTransaction;
  38.   FDQuery2 := TFDQuery.Create(Self);
  39.   FDQuery2.Connection := FDConnection2;
  40.   FDQuery2.Transaction := FDTransaction2;
  41.   FDQuery2.SQL.Text := 'insert into k$attachment (id) values(501)';
  42.   FDQuery2.ExecSQL;
  43.   //
  44.   FDTransaction1.Rollback;
  45.   FDTransaction2.Rollback;
  46.   ShowMessage('Ok');
  47. finally
  48.   FDConnection1.Free; FDConnection2.Free; FDTransaction1.Free; FDTransaction2.Free; FDQuery1.Free; FDQuery2.Free;
  49. end; end;
  50.  
  51. procedure TForm1.Button2Click(Sender: TObject);
  52. var
  53.   FDConnection1, FDConnection2: TFDConnection; FDTransaction: TFDTransaction; FDQuery1, FDQuery2: TFDQuery;
  54. begin try
  55.   FDConnection1 := nil; FDConnection2 := nil; FDTransaction := nil; FDQuery1 := nil; FDQuery2 := nil;
  56.   //
  57.   FDTransaction := TFDTransaction.Create(Self);
  58.   FDTransaction.Options.AutoCommit := FALSE;
  59.   FDTransaction.Options.DisconnectAction := xdRollback;
  60.   //
  61.   FDConnection1 := TFDConnection.Create(Self);
  62.   FDConnection1.Params.Clear;
  63.   FDConnection1.Params.Add('Database=d:\Data5\HBACKUP\TEST\HM.kfb');
  64.   FDConnection1.Params.Add('User_Name=sysdba');
  65.   FDConnection1.Params.Add('Password=masterkey');
  66.   FDConnection1.Params.Add('DriverID=FB');
  67.   FDConnection1.LoginPrompt := FALSE;
  68.   FDConnection1.Transaction := FDTransaction;
  69.   FDConnection1.Connected := TRUE;
  70.   //
  71.   FDConnection2 := TFDConnection.Create(Self);
  72.   FDConnection2.Params.Clear;
  73.   FDConnection2.Params.Add('Database=d:\Data5\HBACKUP\TEST\HM2.kfb');
  74.   FDConnection2.Params.Add('User_Name=sysdba');
  75.   FDConnection2.Params.Add('Password=masterkey');
  76.   FDConnection2.Params.Add('DriverID=FB');
  77.   FDConnection2.LoginPrompt := FALSE;
  78.   FDConnection2.Transaction := FDTransaction;
  79.   FDConnection2.Connected := TRUE;
  80.   //
  81.   FDTransaction.StartTransaction;
  82.   FDQuery1 := TFDQuery.Create(Self);
  83.   FDQuery1.Connection := FDConnection1;
  84.   FDQuery1.Transaction := FDTransaction;
  85.   FDQuery1.SQL.Text := 'insert into k$attachment (id) values(600)';
  86.   FDQuery1.ExecSQL;
  87.   FDQuery2 := TFDQuery.Create(Self);
  88.   FDQuery2.Connection := FDConnection2;
  89.   FDQuery2.Transaction := FDTransaction;
  90.   FDQuery2.SQL.Text := 'insert into k$attachment (id) values(601)';
  91.   FDQuery2.ExecSQL;
  92.   //
  93.   FDTransaction.Rollback;
  94.   ShowMessage('Ok');
  95. finally
  96.   FDConnection1.Free; FDConnection2.Free; FDTransaction.Free; FDQuery1.Free; FDQuery2.Free;
  97. end; end;
  98.  

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3565
  • Karma: 35
    • Verze Delphi: XE7 professional
Re:Společná FDTransaction pro více FDConnection
« Odpověď #3 kdy: 23-10-2018, 15:01:31 »
Problém je v tom, že pristupuješ k dvom rôznym DB. A to v jednej transakcii nie je možné.
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline jd

  • Nováček
  • *
  • Příspěvků: 13
  • Karma: 0
    • Verze Delphi: D6, XE6, Berlin
Re:Společná FDTransaction pro více FDConnection
« Odpověď #4 kdy: 23-10-2018, 15:57:31 »
V IBX (IBDatabase/IBTransaction) to mozne je.

Offline KarelHorky

  • Plnoletý
  • ***
  • Příspěvků: 176
  • Karma: 8
    • Verze Delphi: 7, XE6
Re:Společná FDTransaction pro více FDConnection
« Odpověď #5 kdy: 23-10-2018, 16:31:41 »
Pokud nejde ve FireDac řídit dvě databáze společnou transakcí, není to pro mně dobrá zpráva. Ve starším projektu v Delphi 7 jsem měl v komponentách IBExpres dvě databáze řízené společnou transakcí. Plánuju to časem všechno převést do nových Delphi a na FireDac. Tady pak bude nutné ponechat IBX.  :(
K.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1285
  • Karma: 56
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Společná FDTransaction pro více FDConnection
« Odpověď #6 kdy: 23-10-2018, 17:12:29 »
Pokud nejde ve FireDac řídit dvě databáze společnou transakcí, není to pro mně dobrá zpráva. Ve starším projektu v Delphi 7 jsem měl v komponentách IBExpres dvě databáze řízené společnou transakcí. Plánuju to časem všechno převést do nových Delphi a na FireDac. Tady pak bude nutné ponechat IBX.  :(
K.

A RDBMS podporuji transakce mezi connection sessions?
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline paja666

  • Nováček
  • *
  • Příspěvků: 14
  • Karma: 0
    • Verze Delphi: 10.1.2 Berlin
Re:Společná FDTransaction pro více FDConnection
« Odpověď #7 kdy: 23-10-2018, 19:28:12 »
Citace
A RDBMS podporuji transakce mezi connection sessions?

Ano, podporuje. https://www.firebirdsql.org/pdfmanual/html/ufb-cs-multidb.html

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1285
  • Karma: 56
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Společná FDTransaction pro více FDConnection
« Odpověď #8 kdy: 23-10-2018, 23:58:04 »
Citace
A RDBMS podporuji transakce mezi connection sessions?

Ano, podporuje. https://www.firebirdsql.org/pdfmanual/html/ufb-cs-multidb.html

V tom pripade to nebude neproveditelne. Jen tedy vlastnim resenim volajicim Firebird klient API. Mrknu na to az nainstaluju Delphi...
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1285
  • Karma: 56
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Společná FDTransaction pro více FDConnection
« Odpověď #9 kdy: 24-10-2018, 14:29:35 »
Teoreticky by to mohlo byt mozne na fyzicke urovni (TIBTransaction totiz obsahuje kolekci databazi a pro start transakce pouziva funkci isc_start_multiple). Jen je treba rucne nastavit parametry transakce tak jak se deje uvnitr metody TFDPhysIBTransactionBase.InternalChanged. Napr. (netestovano!):

Kód: Delphi [Vybrat]
  1. uses
  2.   FireDAC.Phys.IBWrapper;
  3.  
  4. var
  5.   DatabaseOne: TIBDatabase;
  6.   DatabaseTwo: TIBDatabase;
  7.   Transaction: TIBTransaction;
  8. begin
  9.   DatabaseOne := TObject(FDConnection1.CliObj) as TIBDatabase;
  10.   DatabaseTwo := TObject(FDConnection2.CliObj) as TIBDatabase;
  11.  
  12.   Transaction := TIBTransaction.Create(DatabaseOne.Env, nil);
  13.   try
  14.     Transaction.Params.Add('write'); // nastaveni parametru transakce, viz. TFDPhysIBTransactionBase.InternalChanged
  15.  
  16.     Transaction.AddDatabase(DatabaseOne); // pridani databaze 1
  17.     Transaction.AddDatabase(DatabaseTwo); // pridani databaze 2 (lze pridat az 16)
  18.  
  19.     Transaction.StartTransaction;
  20.     try
  21.       ...
  22.       Transaction.Commit;
  23.     except
  24.       Transaction.Rollback;
  25.       raise;
  26.     end;
  27.   finally
  28.     Transaction.Free;
  29.   end;
  30. end;

Vzhledem k moznosti paralelniho startu nekolika transakci by nemelo dochazet k problemum v pripade kdy pouzite connection objekty (v ukazce FDConnection1 a FDConnection2) budou mit zrovna nastartovane vlastni transakce.

Samozrejme se takova vec da zabalit do uhledne komponenty...
« Poslední změna: 24-10-2018, 15:02:43 od Delfin »
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1285
  • Karma: 56
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Společná FDTransaction pro více FDConnection
« Odpověď #10 kdy: 27-10-2018, 17:49:28 »
Kdyz nad tim ted zpetne uvazuju, asi to nebude zcela bez problemu. Objekty jenz spousti SQL prikazy totiz budou stale pozadovat od propojeneho connection objektu implicitni rizeni transakci (cemuz je treba v pripade vlastniho rizeni zamezit). Mam vsak pocit ze bylo mozne nejakym parametrem rucni rizeni nastavit. Jeste se k tomu vratim...
I'm a soldier, so don't panic! I know the underground! I like WTFPL license! No more Google, go duck, go!

 

S rychlou odpovědí můžete používat BB kódy a emotikony jako v běžném okně pro odpověď, ale daleko rychleji.

Jméno: E-mail:
Ověření:
Datový typ v Delphi, který má True a False: