Autor Téma: Zmena kódu - ísť do nej?  (Přečteno 694 krát)

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5591
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Zmena kódu - ísť do nej?
« kdy: 27-11-2020, 09:19:09 »

Kód: Delphi [Vybrat]
  1. // Teraz mám
  2.     class function FbTransaction(AAuto, AReadOnly: Boolean; AIsolation: TFDTxIsolation = xiReadCommitted):
  3.       TFDTransaction;
  4.     class procedure QryOpen(const AQuery: TFDQuery; AFieldList: TList<TField>); static;
  5. // Uvažujem o zmene
  6.     class procedure QryOpen(const AQuery: TFDQuery; AFieldList: TList<TField>; AutoCommit, ReadOnly, NewTransaction: Boolean;
  7.       Transaction: TFDTransaction); static;
Súčasný stav:
  Query.Transaction := FbTransaction(...);
  Query1.Transaction := Query.Transaction;
  ...
  QryOpen(Query, ...);
  QryOpen(Query1, ...);
.
Predstava nového stavu
  QryOpen(Query, ...);
  QryOpen(Query1, ..., Query.Transaction);
.
Vypadli by mi riadky, kde sa narába s Transaction. Ostali by mi len riadky QryOpen(Query, ...);
.
Neviem sa rozhodnúť, či do toho ísť. Stojí to za to? Výhody a nevýhody:
  • Stráca sa vizuálny prehľad o transakciách
  • Je menej kódu - to je celý zámer/cieľ úvahy
  • Stále mám k dispozícii pôvodné riešenie. Prípadne class procedure QryOpen(); overload;
Funkcia QryOpen asi nebude úplne univerzálna. Možno mám zlý odhad
« Poslední změna: 27-11-2020, 09:26:15 od Stanislav Hruška »
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3103
  • Karma: 135
    • Verze Delphi: D2007, XE3, DX10
Re:Zmena kódu - ísť do nej?
« Odpověď #1 kdy: 27-11-2020, 13:58:08 »
Stráca sa vizuálny prehľad o transakciách
Myslim, ze si to zbytecne zneprehlednujes: obvykly zpusob prace s transakcemi je takovy, ze je jejich vytvareni/zahajovani/ukoncovani/ruseni explicitne zapsano na jednom miste a zbytku operaci se predava instance explicitni transakce jako parametr. A pokud se nepreda tj. bud se neuvede, nebo se preda nil (osobne kvuli srozumitelnosti a udrzovatelnosti preferuju), tak se vetsinou pouziva nejaka implitni transakce spojena s navazanym spojenim na DB vcetne tech ruznych autocomit aj., protoze kdyz pracujes v rezimu autocommit, tak vlastne o zadne transakce nestojis. A rekl bych, ze prace s implicitni transakci funguje pro vetsinu ruznych DB connectivit.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5591
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Zmena kódu - ísť do nej?
« Odpověď #2 kdy: 27-11-2020, 14:23:30 »
Ďakujem. Keďže mám problém s cudzími slovami, tak som si pozrel v slovníku čo presne znamená implicitne a explicitne.
Potom som už pochopil čo a ako to myslíš.
Používam Firebird + FireDAC. Musím sa pozrieť ako to tam presne je.
Asi to bude tak, že dám na DataModul Connection + TransactionAuto, ktoré si prepojím. Tým pádom nebudem riešiť transakciu pre SELECT. Ostatné si musím lepšie premyslieť.
Ako píšeš, pre všetky SQL typu SELECT mi postačuje AutoCommit = True a ReadOnly = True.
Tu sa mi bijú dva postupy.
  • Tu popísaný spôsob
  • Vytvoriť a zničiť transakciu pri každom použití. Taký príklad tu dal Jirka a Jan Fiala ho podporil.
Alebo oba spôsoby vhodne skombinovať.
Ďakujem.
.
Samozrejme, že sú pre SELECT aj výnimky. U mňa výpočet vyúčtovania, kde všetky akcie voči DB musia byť v jedinej transakcii. Používam tam GTT. To si viem ustrážiť.
.
PS Ja som to už vlastne zrealizoval, ale to nevadí.
« Poslední změna: 27-11-2020, 14:26:53 od Stanislav Hruška »
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3103
  • Karma: 135
    • Verze Delphi: D2007, XE3, DX10
Re:Zmena kódu - ísť do nej?
« Odpověď #3 kdy: 27-11-2020, 18:26:04 »
Alebo oba spôsoby vhodne skombinovať.
Jasne ze se to kombinuje:

 - ciste s autocommit DB aplikaci nenapises
 - explicitne vytvaret a ridit transakce tam, kde to k nicemu neni, je hloupost: napr. vytvaret autocommit transakci je nosenim drivi do lesa atd.



Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5591
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Zmena kódu - ísť do nej?
« Odpověď #4 kdy: 27-11-2020, 21:07:06 »

Neviem si to (kostru) v mojej hlave predstaviť!
Použitie je
  • Transaction.StartTransaction;  // Samé sa to neurobí a dať to na jedno miesto neviem
  • Query SELECT.Open // zamiešaný aj viackrát hockde nižšie
  • Query.ExecSQL/Execute;  // rôzny počet Query
  • Table.Post;
  • Query.ExecSQL/Execute;  // rôzny počet Query
  • Transaction.Commit;  // Samé sa to neurobí a dať to na jedno miesto neviem
Nejaký predok to nerieši, lebo je problém s miestom volania inherited.
Poslať všetky Query a Table do nejakého objektu nejde, nakoľko sú bežne pripravované v (vnorených) cykloch
.
A toto si neviem dať dokopy s
Citace
obvykly zpusob prace s transakcemi je takovy, ze je jejich vytvareni/zahajovani/ukoncovani/ruseni explicitne zapsano na jednom miste a zbytku operaci se predava instance explicitni transakce jako parametr
Lebo mám nejakú metódu triedy (DataOK, Post) v ktorej to všetko robím.
Ako to tam prepašujem - "vytvareni/zahajovani/ukoncovani/ruseni"?
*********************************************************************************
Podrobnejší popis:
Mám 4 stavy:
  • Query SELECT - ten je jasný. Tu ho ignrujeme
  • Table.Post - na formulári môžem mať niekoľko tabuliek. Pre každý podformulár typicky jednu. V jednom okamihu sa pracuje len s jediným formulárom.
  • Query INSERT INTO/EDIT
  • Query DELETE
Všetky tri stavy vyžadujú Transaction Autocommit = False, ReadOnly = False. Prípady 3 a 4 sú z pohľadu problému identické.
Terajšia prax:
Table musí mať počas životnosti formulára aktívnu transakciu. Query majú mať transakciu až v momente použitia. To môžem riešiť dvoma spôsobmi:
  • Query.Transaction := Transaction.Creater();
  • Query.Transaction := Table.Transaction;
Mám dva typické/základné prípady použitia.
  • Viď hore "Použitie je"
  • To isté bez Table.Post;
  • Tu musia byť Query.Transaction := Table.Transaction;
  • Predpokladám Query.Transaction := Transaction.Creater();
Zistil som, že mám knihu (ktorej obsah som nepoznal), kde mám uvedených pár pattern v Delphi. Ako prvé tam je Factory.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5591
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Zmena kódu - ísť do nej?
« Odpověď #5 kdy: 27-11-2020, 21:24:39 »
Edit: za Transaction.Commit nasleduje AktualizujKopuVecí.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3103
  • Karma: 135
    • Verze Delphi: D2007, XE3, DX10
Re:Zmena kódu - ísť do nej?
« Odpověď #6 kdy: 28-11-2020, 09:24:39 »
Asi zapomen na to, co jsem ti napsal, protoze ja mam dojem, ze se motame porad dokola. Uz pred mesicem ti JF psal, ze pokud pracujes jen s table (bez CachedUpdates), tak vlastne zadnou transakci nepotrebujes resp. FireDac ma v kazdem spojeni jednu implicitni s autocommit...

  • Transaction.StartTransaction;  // Samé sa to neurobí a dať to na jedno miesto neviem
  • Query SELECT.Open // zamiešaný aj viackrát hockde nižšie
  • Query.ExecSQL/Execute;  // rôzny počet Query
  • Table.Post;
  • Query.ExecSQL/Execute;  // rôzny počet Query
  • Transaction.Commit;  // Samé sa to neurobí a dať to na jedno miesto neviem
Nechapu: co delas pred Post s ruznymi query? Tam bych ocekaval vsude jen cteni dat...

Prece normalni postup ma 2 faze: nacteni dat tj. krome specialnich pripadu nejaka default readcommited transakce, u FB lze mit trvale zahajenou RO  transakci a pouzivat ji vsude v ramci main threadu.

A na vlastni presun postnutych dat do DB se vytvari explicitni txn na co nejkratsi dobu -> tj. pokud to nemas rozfrcane nejakymi komponentami po vsech certech, tak neco takoveho:
Kód: Delphi [Vybrat]
  1. txn := TxnFactory.DejMiTransakciProZapis;
  2. try
  3.   txn.StartTransaction;
  4.   try
  5.      NecoDelejSTransakci(txn, ...);
  6.      txn.Commit;
  7.   except
  8.     tnx.Rollback;
  9.     raise;
  10.   end;
  11. finally
  12.   txn.Free;
  13. end;
  14.  
Do factory by se dalo presunout i to zahajeni transakce napr.
Kód: Delphi [Vybrat]
  1. txn := TxnFactory.DejMiZahajenouTransakciProZapis;
  2. try
  3.   try
  4.     ...
  5.  
ale ja bych to nedelal, protoze by to nejspis vedlo k lajdackemu uvolnovani

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5591
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Zmena kódu - ísť do nej?
« Odpověď #7 kdy: 28-11-2020, 09:49:04 »
Citace
Nechapu: co delas pred Post s ruznymi query? Tam bych ocekaval vsude jen cteni dat...
A tie načítané údaje použijem ako (výpočet) hodnoty pre parametre.
Neriešim Table.Transaction ani QuerySelect.Transaction.
Citace
tak vlastne zadnou transakci nepotrebujes resp. FireDac ma v kazdem spojeni jednu implicitni s autocommit...
O tom neviem. To si musím pozrieť. Zamýšľam sa len nad tým, ako to mať všetko na jednom mieste - ak to nie je AutoCommit. Čo je celkom bežné.
Ak to budem mať na jednom mieste, ako sa k tomu dostanem. Mne vždy vychádza, že to bude obdoba toho čo mám. Buď priamo do kódu zapíšem StartTransaction či zavolám funkciu ktorá to urobí, alebo zavolám funkciu z "jedného miesta". Prašť jako uhoď.
V kóde budem mať vždy rovnaký počet riadkov a budem to zakaždým volať ručne. Nebude sa to vykonávať automaticky. Čo je za tým je z tohto pohľadu nepodstatné.
Ja som
Citace
obvykly zpusob prace s transakcemi je takovy, ze je jejich vytvareni/zahajovani/ukoncovani/ruseni explicitne zapsano na jednom miste a zbytku operaci se predava instance explicitni transakce jako parametr
pochopil tak, že sa zbavím volaní funkcií, ktoré teraz mám. Asi som to pochopil zle.
Teraz mám jednotku s triedou, kde sú všetky metódy class. Tým pádom to mám všetko na jednom mieste.
Mám to chápať tak, že som vlastne splnil tu vyššie citované?
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3103
  • Karma: 135
    • Verze Delphi: D2007, XE3, DX10
Re:Zmena kódu - ísť do nej?
« Odpověď #8 kdy: 28-11-2020, 10:12:56 »
A tie načítané údaje použijem ako (výpočet) hodnoty pre parametre.
Nechapu. proc ctes data v transakci, ve ktere soucasne postujes data z tabulky, pokud se nejedna o serializable transakci...

Citace
Mám to chápať tak, že som vlastne splnil tu vyššie citované?
Ne, na jednom miste cele rizeni transakce tj. ukazka kodu, ktery jsem tu posilal v predchozim prispevku.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5591
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Zmena kódu - ísť do nej?
« Odpověď #9 kdy: 28-11-2020, 11:45:04 »
Citace
Nechapu. proc ctes data v transakci, ve ktere soucasne postujes data z tabulky, pokud se nejedna o serializable transakci...
Možno to tak vyzerá, ale nerobím to.
Citace
Mám to chápať tak, že som vlastne splnil tu vyššie citované?
Ne, na jednom miste cele rizeni transakce tj. ukazka kodu, ktery jsem tu posilal v predchozim prispevku.
Aha. Už mi to trochu došlo. Aj tak mi predstava realizácie pokuľháva. Hlavne ak tú transakciu mám priradiť viacerým Query.
Hlavne v časti
Kód: Delphi [Vybrat]
  1.  NecoDelejSTransakci(txn, ...);
Skúsim do toho zapojiť hlavu.
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3103
  • Karma: 135
    • Verze Delphi: D2007, XE3, DX10
Re:Zmena kódu - ísť do nej?
« Odpověď #10 kdy: 28-11-2020, 13:22:19 »
Aj tak mi predstava realizácie pokuľháva. Hlavne ak tú transakciu mám priradiť viacerým Query.
napr.
Kód: Delphi [Vybrat]
  1. procedure DelamNecoSTransakci(ATxn:TFDCustomTransaction; ....);
  2. begin
  3.   var q1 := XxxFactory.DejMiQuery(ATxn);
  4.   try
  5.     var q2 := XxxFactory.DejMiQuery(ATxn);
  6.     try
  7.       var q3 := XxxFactory.DejMiQuery(ATxn);
  8.       try
  9.  
  10.         ...
  11.  
  12.       finally
  13.          q3.Free;
  14.       end;
  15.     finally
  16.       q2.Free;
  17.     end;
  18.   finally
  19.     q.Free;
  20.   end;
  21. end;
  22.  
  23.  

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5591
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Zmena kódu - ísť do nej?
« Odpověď #11 kdy: 28-11-2020, 13:43:11 »
Ďakujem, uvidím či sa mi to podarí aplikovať na to čo už mám. V praxi je to tak, že sa v drvivej väčšine prípadov vymykajú z rámca ukážok :-\
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3103
  • Karma: 135
    • Verze Delphi: D2007, XE3, DX10
Re:Zmena kódu - ísť do nej?
« Odpověď #12 kdy: 28-11-2020, 16:40:15 »
Ďakujem, uvidím či sa mi to podarí aplikovať na to čo už mám. V praxi je to tak, že sa v drvivej väčšine prípadov vymykajú z rámca ukážok :-\
Kdybych se do neceho poustel za ucelem zkvalitneni kodu, tak bych si udelal interfejs ISQLQuery, ten implementoval a vsude operoval jen s interfejsy:
Kód: Delphi [Vybrat]
  1.     procedure DelamNecoSTransakci(ATxn:TFDCustomTransaction; ....);
  2.     begin
  3.       var iQ1 := XxxFactory.DejMiQuery(ATxn);
  4.       var iQ2 := XxxFactory.DejMiQuery(ATxn);
  5.       var iQ3 := XxxFactory.DejMiQuery(ATxn);
  6.  
  7.             ...
  8.      
  9.     end;
  10.  
     
To uz by odpovidalo tomu, na co je clovek zvykly z modelrnich jazyku
     

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 5591
  • Karma: 42
    • Verze Delphi: W10 + Delphi 10.4 professional
Re:Zmena kódu - ísť do nej?
« Odpověď #13 kdy: 29-11-2020, 10:57:16 »
Zámerom je čo najjednoduchšie riešenie pre mňa = čo najmenej kódu.
Pokusmi, úvahami a existujúcim stavom som dospel k nasledujúcemu
Stav:
  • Používam DB komponenty
  • K nim DataSource -> Table. Aby som nemusel ošetrovať text pre Query. Len v mimoriadnych situáciách Query. Tieto ďalej neberiem do úvahy
DataModul obsahuje
  • FDConnection
  • TransactionTableAuto: AutoCommit, ReadOnly = True
  • TransactionTableManually: AutoCommit, ReadOnly = False
FDConnection:
  • .Transaction := TransactionTableAuto;
  • .UpdateTransaction := TransactionTableManually;
Formuláre
FDTable:
  • vždy len staticky
  • .Connection := FDConnection;  // Nič viac. Ja som si pôvodne myslel, že v každej tabuľke musím definovať aj transakcie
FDQuery:
  • vždy len dynamicky
  • .UPdaTransaction := nil;
QuerySelect.Transaction:
  • buď TransactionTableAuto, alebo
  • pridať na DataModul TransactionQueryAuto
  • ju dynamicky
Myslím si, že nebudú problémy ak použijem TransactionTableAuto
QueryInsUpdDel.Transaction:
  • Ak je v procese použitá FDTable, tak to musí byť TransactionTableManually
V ostatných prípadoch:
  • TransactionTableAuto alebo
  • vytvárať ju dynamicky
Volím TransactionTableManually. Tým nemôžem nič pokaziť.
.
Prosím, je moja úvaha správna? Prosím o potvrdenie alebo zamietnutie!
Takto budem mať len dve existujúce transakcie, ako to niekedy napísal pf1957. O ich životnosť sa nestarám. Padá riešenie podľa Jirku
« Poslední změna: 29-11-2020, 10:59:58 od Stanislav Hruška »
W10 64b, Delphi 10.4, FireBird 3.05
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 3103
  • Karma: 135
    • Verze Delphi: D2007, XE3, DX10
Re:Zmena kódu - ísť do nej?
« Odpověď #14 kdy: 29-11-2020, 19:22:09 »
   
  • Používam DB komponenty
  • K nim DataSource -> Table.

Mozna je to tim, ze jsem nikdy Table k nicemu nepouzil, ale moje predstava o tom siditku je takova, ze je to potomek TDataset, kteremu se zada TableName a ono si na Open() vygeneruje select a podle nastaveni options nacte nejake zaznamy z dane DB tabulky. A kdyz se tomu meni obsah, tak se zmena potvrzuje volanim Post(), ktere automaticky vygeneruje insert/update/delete SQL command a vykona ho (tohle neplati pro CachedUpdates).

Ale mohu se mylit. Ovsem je-li moje predstava v principu spravna, tak nechapu, proc chces manualne ridit transakci, ve ktere se meni obsah jedne DB tabulky, protoze v jeden cas menis jeden record a to se ti bud povede nebo ne, a to si osetris. Na to z transakcniho hlediska zadnou transakci nepotrebujes => staci ti AutoCommit=true.

Pro vsechny ostatni pripady, kdy je zmena obsahu DB realizovana vice nez jednim SQL prikazem, potrebujes explicitne (manualne) rizenou transakci, ale tu je vhodne s nicim nesdilet tj. nema co delat na DataModulu a vytvari/startuje/ukoncuje/rusi se, jak jsem ti naznacoval naposledy vcera.

Citace
DataModul obsahuje
  • FDConnection
  • TransactionTableAuto: AutoCommit, ReadOnly = True
  • TransactionTableManually: AutoCommit, ReadOnly = False
S ohledem na vyse napsane my tohle nedava smysl a pro Interbase/Firebird bych udelal v DataModulu:
  • FDConnection
  • ReadOnlyTransaction: AutoCommit = False, ReadOnly = True
  • ReadWriteTransaction: AutoCommit = true, ReadOnly = False
A ReadOnlyTransaction bych po uspesnem pripojeni FDConnection na server zahajil a nechal aktivni, pred odpojenim se od serveru bych ji rollnul back.

Citace
FDConnection:
  • .Transaction := TransactionTableAuto;
  • .UpdateTransaction := TransactionTableManually;
Tohle by bylo v zasade spravne stejne jako predavani pouze FDConnection do tabulky, jen ty transakce zmenit/prejmenovat podle vyse uvedeneho.

U ostatnich query zapomenout na property UpdateTransaction aj. bud pouzivat pro property Transaction mistne rizenou transakci, nebo ji nechat nil podobne jako u tabulky (vezmou se transakce z FDConnection).
« Poslední změna: 29-11-2020, 19:42:16 od pf1957 »