Forum Delphi.cz

Databáze => Firebird a Interbase => Téma založeno: Stanislav Hruška 20-10-2020, 21:46:09

Název: Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 20-10-2020, 21:46:09
Včera som celý blažený išiel spať. Vkladanie záznamov OK. A dnes takýto šok. Ja začnem veriť, že som naozaj zakliaty, alebo som ... Jaj to už dávno viem, že som.  Skúšam najjednoduchší prípad - práca priamo s jedinou tabuľkou.
Všetko viacnásobne skontrolované. Včera som mal xiUnspecified, čo je vraj xiReadCommitted. Začalo to fungovať, až keď som to zmenil na xiReadCommitted.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 20-10-2020, 21:56:12
Všetko viacnásobne skontrolované. Včera som mal xiUnspecified, čo je vraj xiReadCommitted.
Zkus někdy Google  - zabere to asi 8 sekund ..
http://docwiki.embarcadero.com/Libraries/Sydney/en/FireDAC.Stan.Option.TFDTxOptions.Isolation (http://docwiki.embarcadero.com/Libraries/Sydney/en/FireDAC.Stan.Option.TFDTxOptions.Isolation)
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 20-10-2020, 22:02:04
Ale na FB som čítal, čo som napísal. Ak som to nepoplietol.
Ale to nič nemení na veci, keďže mám nastavené xiReadCommitted. Vyskúšal som aj xiDirty čo je prakticky nulová izolácia. Rovnaký výsledok.
Na tom internete som si to všetko prešiel. FireDAC aj FB.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 20-10-2020, 22:16:14
Tak som na dôvod prišiel. Transakcia je aktívna a ja som ju spúšťal ešte raz. Keď som urobil Rollback, tak to je OK.
Narýchlo som hľadal, kde to spúšťam, ale som to nenašiel. Nevadí, budem krokovať.
Teda robí chyby čo ich je naozaj problém objaviť.
.
Ospravedlňujem sa zbytočné zahlcovanie webu.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 20-10-2020, 22:17:37
Ale na FB som čítal, čo som napísal. Ak som to nepoplietol.

No  nevím co řešíš, ale to co TFDTxOptions.Isolation řeší je jak tvá aktuální transakce přistupuje k ostatním transakcím (viditelnost)
a na to jestli to něco (ne)ukládá  ve tvé transakci by nemělo mít vliv (snad jen konkureční zápisy).
doporučuji knihu od Pavla Císaře Interbase/Firebird 
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: pf1957 20-10-2020, 22:18:52
Skúšam najjednoduchší prípad - práca priamo s jedinou tabuľkou.
Jako 1. krok se vykasli na UpdateTransaction a pouzij jen jednu ReadCommited RW transakci.
Jako 2. krok, kdyz to stale nebude videt si dej bkpt po commit a podivej se vedle z nejakeho SQL Manageru na obsah DB, jestli je to opravdu commitnute.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: pf1957 20-10-2020, 22:37:45
Narýchlo som hľadal, kde to spúšťam, ale som to nenašiel. Nevadí, budem krokovať.
No tu transakci nejspis nastartuje ten automaticky rezim jeste pred tim, nez bys ho pripadne vypnul tim StartTransaction (pokud se to tedy u FD vubec vypina).
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 20-10-2020, 23:50:23
Nie. Spúšťam ich sám. Ale používal som Close/FreeAndNil a to neuzatvorí transakciu. Takže to musím celé prejsť. Len teraz vidím, koľko otvorených transakcií mi viselo vo vzduchu.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 00:42:02
Jako 1. krok se vykasli na UpdateTransaction a pouzij jen jednu ReadCommited RW transakci.
Jako 2. krok, kdyz to stale nebude videt si dej bkpt po commit a podivej se vedle z nejakeho SQL Manageru na obsah DB, jestli je to opravdu commitnute.

Při testovaní bych to ponechal, ale při ostrém provozu bych se radši držel zásady transakce RW   bych držel aktivní pouze po dobu vlastního zapisu a pak deaktivovat
(což není commit ani rollback) a pro prohlížení dat a tisk vytvařet pouze Read only transakce .
Já používám  transakce níže uvedeným systémem a mám jistotu že mi nikde žadná transakce nezustane viset.

Kód: [Vybrat]
  function GetPocetKatastru: Integer;
var
  Q1: TpFibQuery;
  i: Integer;
  ASQL: string;
  IBTransactionV: TpFIBTransaction;

  begin
  Result := 0;
  ASQL := Format('SELECT COUNT(*) FROM KATASTR ', []);
  i := 0;
  VytvorCteciTransakci(IBTransactionV);
  Q1 := TpFibQuery.Create(nil);
  try
    try
      Q1.Database := DM1.pFIBDatabase1;
      Q1.Close;
      Q1.Transaction := IBTransactionV;

      if not Q1.Transaction.Active then       Q1.Transaction.StartTransaction;

      Q1.SQL.Add(ASQL);
      Q1.ExecQuery;
      Result := Q1.FieldByName('COUNT').AsInteger;
      Q1.Close;

    except
    {$I 'fibq-except.inc'}
    end;

  finally
    FreeAndNil(IBTransactionV);
    FreeAndNil(Q1);
  end;
end;

Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jan Fiala 21-10-2020, 06:54:09
To je samozřejmě tak, jak by se proti SQL serveru pracovat mělo. Ale on nepoužívá SQL, ale pracuje s Table.
Takže má otevřenou transakci od okamžiku, kdy zavolá edit, až po post (uživatel začne editovat a odskočí si na oběd).
Na problémy narazí v okamžiku, kdy bude ctít používat víceuživatelský přístup, uživatelé si budou zamykat záznamy/tabulky, začne řešit, proč mu tam vznikají deadlocky.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: pf1957 21-10-2020, 07:56:30
Nie. Spúšťam ich sám. Ale používal som Close/FreeAndNil a to neuzatvorí transakciu. Takže to musím celé prejsť. Len teraz vidím, koľko otvorených transakcií mi viselo vo vzduchu.
No to jsem myslel, ze uz jsi vyresil nekdy pred tydnem, nebo kdy to bylo  :o
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 09:29:48
Citace
No to jsem myslel, ze uz jsi vyresil nekdy pred tydnem, nebo kdy to bylo 
To je pravda. Ale vtedy som mal 3 transakcie. Teraz pre SQL používam len jedinú - manual a problém bol znovu na svete.
Citace
To je samozřejmě tak, jak by se proti SQL serveru pracovat mělo. Ale on nepoužívá SQL, ale pracuje s Table.
Takže má otevřenou transakci od okamžiku, kdy zavolá edit, až po post (uživatel začne editovat a odskočí si na oběd).
Na problémy narazí v okamžiku, kdy bude ctít používat víceuživatelský přístup, uživatelé si budou zamykat záznamy/tabulky, začne řešit, proč mu tam vznikají deadlocky.
Ja mám Table jedine kvôli DB komponentom. Ináč vždy všade používam Query. FB zamykanie záznamov (asi ani tabuliek) nemá. K jednému SVB má prístup len jediný užívateľ. Takže konkurenčný prístup nehrozí.
To Jirka: ja som si myslel, že spojenie/transakciu s DB treba stále držať nažive. Že to má vysokú réžiu a podobné úvahy. Prerobím to podľa Tvojho príkladu. Pod výrazom "visia mi transakcie" som mal na mysli, že sú stále aktívne.
Ďakujem za kód :-* (iný vhodný smieško tu nie je). Tie zásady som si nemal kde prečítať.
Edit:
DB grid nepoužívam. Pôvodne som to mal bez DB komponentov. Už si nepamätám na dôvod zmeny. Ale tu na tom webe je spomenutý.

Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 09:39:38
To je samozřejmě tak, jak by se proti SQL serveru pracovat mělo. Ale on nepoužívá SQL, ale pracuje s Table.
Já to posílal jako princip jak se nejlepe vyhnout zatoulaným a neuvolněným transakcím. 
Reagoval jsem na postup pf  aby se používala jedna RW  transakce  na prohlížení i editaci
Nehledě na to že používání Table mi přijde minimálně jsko problematické - například při vytváření kopie dokladu Master/Detail
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jan Fiala 21-10-2020, 09:45:11
To Jirka: ja som si myslel, že spojenie/transakciu s DB treba stále držať nažive. Že to má vysokú réžiu a podobné úvahy.

To platí o spojení (Connection) - to si držíš po běh programu. Transakce naopak zahajuješ a potvrzuješ po co nejkratší nutnou dobu.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 09:51:56
To Jirka: ja som si myslel, že spojenie/transakciu s DB treba stále držať nažive. Že to má vysokú réžiu a podobné úvahy.
To platí o spojení (Connection) - to si držíš po běh programu. Transakce naopak zahajuješ a potvrzuješ po co nejkratší nutnou dobu.
Teraz to tak prerábam. Jirka v príklade stále vytvára a ničí transakcie. To ma zaskočilo. Ale ako písal, je tu 100 % istota.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 09:56:49
Citace
Takže konkurenčný prístup nehrozí.
Nedávno si tady psal že pokud bude zájem o sitovou verzi tak si poridiš vyšší verzi Delphi pro C/S ..
To pak budeš přepisovat aplikaci ? 


Citace
To Jirka: ja som si myslel, že spojenie/transakciu s DB treba stále držať nažive. Že to má vysokú réžiu a podobné úvahy. Prerobím to podľa Tvojho príkladu.
Jen to proboha nepředělávej  žádným hurá systémem. To není záležitost změny jedné procedury, ale kompletní nastavení celé logiky prohlížení a editace dat 


Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: pf1957 21-10-2020, 10:00:19
Reagoval jsem na postup pf  aby se používala jedna RW  transakce  na prohlížení i editaci
Ne, to nebylo mineno, aby se pouzivala jedna RW, ale aby pri lokalizaci problemu pouzil jednu transakci, protoze jestli lze neco dovodit z popisu jeho problemu, tak tam micha autocommit a explicitne rizene transakce.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 10:00:56
Citace
Nedávno si tady psal že pokud bude zájem o sitovou verzi tak si poridiš vyšší verzi Delphi pro C/S ..
To pak budeš přepisovat aplikaci ?
Osobne na to nevidím dôvod.
Citace
Jen to proboha nepředělávej  žádným hurá systémem. To není záležitost změny jedné procedury, ale kompletní nastavení celé logiky prohlížení a editace dat
S tým už mám skúsenosti ;D Ja som si tu ukážku vytlačil. Naštudujem si ju, aby som ju pochopil čo najviac do hĺbky = čo to bude znamenať pre moju logiku v aplikácii.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: pf1957 21-10-2020, 10:03:07
Jirka v príklade stále vytvára a ničí transakcie. To ma zaskočilo. Ale ako písal, je tu 100 % istota.
Hm, vzdyt jsi psal, ze mas buhvi na kolika mistech neukoncene transakce, protoze sis myslel, ze je FreeAndNil ukonci. Tak na co pouzivas FreeAndNil, kdyz ty transakce taky stale nevytvaris  :o

Jsem z tebe Gogo...
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 10:10:33
Ne, to nebylo mineno, aby se pouzivala jedna RW, ale aby pri lokalizaci problemu pouzil jednu transakci, protoze jestli lze neco dovodit z popisu jeho problemu, tak tam micha autocommit a explicitne rizene transakce.
I já to tak pochopil , proto jsem psal, že v testu ano ale v produkční nasazení radši ne .
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 10:13:37
Naštudujem si ju, aby som ju pochopil čo najviac do hĺbky = čo to bude znamenať pre moju logiku v aplikácii.

Tam žádnou "hloubku" nehledej , je to jen princip
-Vytvořím
-Použiji
-Uvolním


Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: pf1957 21-10-2020, 10:35:32
Tam žádnou "hloubku" nehledej , je to jen princip
-Vytvořím
-Použiji
-Uvolním
Ja bych jeste zduraznil Ukoncim tj. standardni pattern:
Kód: Delphi [Vybrat]
  1. ...
  2. txn.StartTransaction;
  3. try
  4.   ...
  5.   txn.Commit;
  6. except
  7.   txn.Rollback;
  8.   raise;
  9. end;
  10. ...
  11. end;
  12.  
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 11:32:08
Jirka v príklade stále vytvára a ničí transakcie. To ma zaskočilo. Ale ako písal, je tu 100 % istota.
Hm, vzdyt jsi psal, ze mas buhvi na kolika mistech neukoncene transakce, protoze sis myslel, ze je FreeAndNil ukonci. Tak na co pouzivas FreeAndNil, kdyz ty transakce taky stale nevytvaris  :o

Jsem z tebe Gogo...
FreeAndNil(MyQuery)
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 11:38:49

Mám niečo podobné
Kód: [Vybrat]
class procedure TFDFunction.QryOpen(const AQuery: TFDQuery; var AFieldList: TList<TField>);
var
  Field: TField;
begin
  Assert(Assigned(AQuery), '  AQuery is nil  ');
  Assert(AQuery.SQL.Text <> '', '  AQuery.SQL.Text is empty  ');
  Assert(Assigned(AFieldList), '  AFieldList is nil  ');
.
  if not AQuery.Transaction.Active then
    AQuery.Transaction.StartTransaction;
.
  try
    if AQuery.Active then
      AQuery.Refresh
    else
      AQuery.Open;
.
    AQuery.First;
.
    if AFieldList.Count > 0 then
      AFieldList.Clear;
.
    for Field in AQuery.Fields do
      AFieldList.Add(Field);
  except
    on E: Exception do
    begin
      E.RaiseOuterException(EAbstractException.Create(EDB_Query_Open, E.Message));
      raise;
    end;
  end;
end;
a k tomu
Kód: [Vybrat]
class function TFDFunction.NewQryRead(const AOwner: TComponent): TFDQuery;
begin
  Result := TFDQuery.Create(AOwner);
  Result.Connection := dtmdBasic.conFOC;
  Result.Transaction := dtmdBasic.fdtrManual;
  Result.FetchOptions.Mode := fmAll;
end;
.
class procedure TFDFunction.FreeAndNilQry(AQuery: TFDQuery; AFieldList: TList<TField>);
begin
  if AQuery.Transaction.Active then
    AQuery.Transaction.Rollback;
.
  FreeAndNil(AQuery);
  FreeAndNil(AFieldList);
end;
Takže by to nemalo byť tak zložité. Do NewQryRead pridám parameter Auto. A bude len jedna NewQuery.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 11:56:17
Len dodatok, že moja obchodná logika nie je komplikovaná. Je pomerne priamočiara.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 12:06:49
Len dodatok, že moja obchodná logika nie je komplikovaná. Je pomerne priamočiara.
;D

Citace
Result := TFDQuery.Create(AOwner);
Proč používáš AOwner když si Query vracíš jako Výsledek funkce ? Není to zbytečné ?

Citace
class procedure TFDFunction.FreeAndNilQry(AQuery: TFDQuery; AFieldList: TList<TField>);
Neměly by být AQuery a AFieldList  předávany odkazem přes var ?
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 12:14:03
Citace
Proč používáš AQwner když si Query vracíš jako Výsledek funkce ? Není to zbytečné ?
Lebo som nerozmýšľal pri definícii ani pri písaní kódu.
Citace
Neměly by být AQuery a AFieldList  předávany odkazem přes var ?
V princípe áno.
Ďakujem.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 12:26:31
Kód: [Vybrat]
if AFieldList.Count > 0 then
      AFieldList.Clear;
.
    for Field in AQuery.Fields do
      AFieldList.Add(Field);

Jen taková drobná přípomínka 
Proč si vytváříš další seznam polí  když se k němu dostaneš kdekoliv přes AQuery.Fields ?
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 12:53:35
Lebo pri opakovanom prístupe, v cykle, to je rýchlejšie. Aj keď v mojom prípade je tento argument skôr úsmevný.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 13:15:58
Lebo pri opakovanom prístupe, v cykle, to je rýchlejšie. Aj keď v mojom prípade je tento argument skôr úsmevný.
Ty to máš změřené ?

A i kdyby to mělo mít nějaké vyznačné zrychlení  tak se to IMHO nevyplatí minimálně oproti
- režii vytváření seznamu
- hlídaní zda tento seznam patří k požadovanému Query
- režii  a hlídaní uvolnování seznamu


 
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 16:42:21

Samozrejme, že nemám. Ako som písal, tých záznamov mám v prevažnej väčšine málo. Rádovo v stovkách. To je vytvorené na základe tunajších diskusií. Už z princípu. Že o tom viem.
Citace
- režii vytváření seznamu
- hlídaní zda tento seznam patří k požadovanému Query
- režii  a hlídaní uvolnování seznamu
Prvé beriem
Druhé - to vlastne nemusím riešiť. Ak spúšťam viac Query naraz, tak majú vlastný zoznam. To je minimum prípadov. Ešte som s tým nemal problém
Tretie - Réžia toho zoznamu je nižšia, než získavanie polí z Query či tabuľky. Preto to odporúčali a používa sa to. Niektorým to celkom pomohlo. Query použijem a hneď záznam zničím. Tam kde som ho vytvoril. Žiaden problém.
.
Trošku k Tvojmu kódu. Viem, že to je len narýchlo urobený príklad. Nerozumiem niektorým veciam.
Kód: [Vybrat]
  VytvorCteciTransakci(IBTransactionV);
...
  if not Q1.Transaction.Active then       Q1.Transaction.StartTransaction;
Ja totiž nepredpokladám, že vytvoríš Transaction a zároveň ju spustíš.
.
Vytvoríš Q1, priradíš jej Database (čo ja nerobím) a nalseduje Q1.Close; Veď nebola otvorená.
Pýtam sa preto, aby som mal istotu, že o niečom neviem.
Nie je potrebné pred použitím FreeAndNil(IBTransactionV); ukončiť transakciu?
Viem, že pri FreeAndNil(Q1); sa zavolá udalosť Close.

Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 18:11:57


Citace
Réžia toho zoznamu je nižšia, než získavanie polí z Query či tabuľky. Preto to odporúčali a používa sa to. Niektorým to celkom pomohlo.
To myslíš toto
https://delphi.cz/post/Pripad-FieldByName.aspx (https://delphi.cz/post/Pripad-FieldByName.aspx)

Citace
Kód: [Vybrat]
  VytvorCteciTransakci(IBTransactionV);
...
  if not Q1.Transaction.Active then       Q1.Transaction.StartTransaction;

Ja totiž nepredpokladám, že vytvoríš Transaction a zároveň ju spustíš.

A proč ne ?

Citace
Nie je potrebné pred použitím FreeAndNil(IBTransactionV); ukončiť transakciu?
No puristicky pojato možná ano.   


Citace
Vytvoríš Q1, priradíš jej Database (čo ja nerobím) a nalseduje Q1.Close; Veď nebola otvorená.
Vycházím z toho že vytvářím instanci cizí komponenty a nevim jaký vychozí stav je zvolil autor komponenty (v této či další verzi dané komponenty)
Tak si zvolené údaje nastavím do požadovaného stavu než s nimi začnu pracovat.

Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 18:22:03
Mám ešte jeden problém, ktorý neviem rozlúsknuť. Volám viacero Query a niektoré aj v cykle.

Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 18:29:45
Citace
To myslíš toto
https://delphi.cz/post/Pripad-FieldByName.aspx (https://delphi.cz/post/Pripad-FieldByName.aspx)
Áno, tam to je vysvetlené. A pár diskusií tu, kde to odporúčali a niektorí sa rozhodli upraviť kód.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 19:04:08
Mám ešte jeden problém, ktorý neviem rozlúsknuť. Volám viacero Query a niektoré aj v cykle.
  • Ako mám vyriešiť tvorbu Transaction. Môže/musí byť len jedna. Jediné riešenie mi napadá pomocou premennej. Teraz priradím tú čo mám v DataModul-e.
  • Ničiť ju nemusím. Myslím si, že rozhodujúce je použiť Commit/RollBack. Alebo sa tu mýlim?

Pokud volám  více Query (nebo cokoliv jiného z databáze) a tvoří to logický celek tak si jednu transakci vytvořím před začátkem cyklu  použiji v celém  cyklu,  pak provedu commit a následně uvolním
Znovu doporučuji projít si knihu od Pavla Císaře
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 19:10:11
Citace
To myslíš toto
https://delphi.cz/post/Pripad-FieldByName.aspx (https://delphi.cz/post/Pripad-FieldByName.aspx)
Áno, tam to je vysvetlené. A pár diskusií tu, kde to odporúčali a niektorí sa rozhodli upraviť kód.
Můžeš poslat úryvek kodu jak to používáš ?
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 19:31:08
Jedna z možností. Nie sú tu vnorené cykly jednotlivých query.
Kód: [Vybrat]
procedure TFlatOwner.FillOtherTables;
var
  I: Integer;
begin
  try
    TFDFunction.QryOpen(FqryOwnerFlat, FlstfldOther);
    FqryHeatingCost_I.Params.ArraySize := FqryOwnerFlat.RecordCount;
    FqryBillingRestBefore_I.Params.ArraySize := FqryOwnerFlat.RecordCount;
    FqryOwnerFlat.ParamByName('FKFOCS').AsInteger := oGlobVar.IDFOC;
.
    for I := 0 to FqryOwnerFlat.RecordCount -1 do
    begin
      FqryHeatingCost_I.ParamByName('FKOWNER_FLAT').AsIntegers[I] := FlstIDOwnerFlat[I];
      FqryBillingRestBefore_I.ParamByName('FKOWNER_FLAT').AsIntegers[I] := FlstIDOwnerFlat[I];
      ....
      FqryOwnerFlat.Next;
    end;
.
    TFDFunction.QryExecute(FqryHeatingCost_I, esInsert, False);
    TFDFunction.QryExecute(FqryBillingRestBefore_I, esInsert, False);
  except //on E: Exception do
    raise;
  end;
end;
Ak má SVB 100 bytov, tak tých záznamov bude 100 + nejaká zmena vlastníkov počas roka. U nás v meste nepoznám SVB, ktoré by malo viac než 104 bytov.
Do tej knihy sa pozriem. Pomocou nej som sa učil FB.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jan Fiala 21-10-2020, 20:03:55
Teraz to tak prerábam. Jirka v príklade stále vytvára a ničí transakcie. To ma zaskočilo. Ale ako písal, je tu 100 % istota.

Představ si transakci jako dávku příkazů - ukládáš údaje do více tabulek a potřebuješ, aby se buď uložily všechny nebo žádné. Nechceš, aby se ti něco uložilo do hlavičky a pak ti spadlo ukládání řádků a uložila se jich třeba jen polovina. Přesně k tomu je transakce - obalí ty příkazy a když vše projde, potvrdíš ji (commit) nebo vše vrátíš (rollback). Protože při zahájení transakce dojde k uzamknutí záznamů (při vkládání pak k uzamknutí dalšího vkládání - identity apod.), tak je ve tvém zájmu, aby vlastní transakce trvala co nejkratší dobu. Ve tvém případě na stisknutí uložení zapneš transakci, provedeš post do všech tabulek a potvrdíš transakci.
Transakce ztrácí smysl, pokud ukládáš jeden záznam do tabulky - tam víš, jestli se uložil nebo ne.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 21-10-2020, 20:39:47
Transakce ztrácí smysl, pokud ukládáš jeden záznam do tabulky - tam víš, jestli se uložil nebo ne.
Tento výrok může být pro někoho matoucí
(už vidím jak Stano zajásal že transakce vlastně nepotřebuje když bude ukladat po jednom záznamu  ;) )
Ale prakticky  každé  napojení musí ve Firebirdu  běžet v nějaké transakci



Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: pf1957 21-10-2020, 21:39:19
Ty to máš změřené ?

A i kdyby to mělo mít nějaké vyznačné zrychlení  tak se to IMHO nevyplatí minimálně oproti
- režii vytváření seznamu
- hlídaní zda tento seznam patří k požadovanému Query
- režii  a hlídaní uvolnování seznamu
My jsme v dobach, kdy tam bylo tupe prochazeni cyklu jeste pred generiky a unicodifikaci Delphi doplnili index na jmena a jestli si to pamatuju, tak se to zrychlilo 4x - ta efektivita zalezi na nejakem strednim poctu poctu poli v aplikaci a co se s temi datasety dela. A kdyz zavedli ty hashovaci funkce, tak jsme to tady taky probirali a zjistilo se, ze jsou skutecne rychle, rychlejsi nez puleni intervalu
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: pf1957 21-10-2020, 21:40:47
FreeAndNil(MyQuery)
Aha, to mi nedoslo.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 22:11:36
Transakce ztrácí smysl, pokud ukládáš jeden záznam do tabulky - tam víš, jestli se uložil nebo ne.
Tento výrok může být pro někoho matoucí
(už vidím jak Stano zajásal že transakce vlastně nepotřebuje když bude ukladat po jednom záznamu  ;) )
Ale prakticky  každé  napojení musí ve Firebirdu  běžet v nějaké transakci
Tak to nie. Práve som odložil knihu, takže viem (aj som vedel), že bez transakcie nedám ani ranu. Vidím, že ku kódu nemáš pripomienku, čo ma teší. Len tu upresním, že pri jednorázovom prístupe k DataSet-u (jeden záznam) zoznam polí nepoužívam. Až také kraviny nerobím.
.

To Fiala: tieto veci viem. V mojom kóde vždy vidíš v jednej funkcii StartTransaction a Commit/Rollback. Chcem tým povedať, že ak spustím transakciu, tak okamžite nasleduje dopyt na DB a okamžité ukončenie transakcie. Vždy to je najkratší čas aký je potrebný na transakciu. Nie je tam nič, čo nie je potrebné pre vykonanie "transakcie". Aj tak ďakujem za príspevok, lebo sa mi to lepšie uloží v pamäti. Ja som mal problém hlavne s úrovňou izolácie.
Citace
Transakce ztrácí smysl, pokud ukládáš jeden záznam do tabulky - tam víš, jestli se uložil nebo ne.
Tak to teda nevidím. Nepoužívam DBGrid ale VST. Ten aktualizujem hneď po Commit. Tak sa mi stalo, že som na formulári videl vo VST záznamy, ktoré v DB neexistovali :) Bol to pre mňa horor.
.
Tie zoznamy ponechám, lebo by to bolo veľa práce ich odstrániť. Pritom si nemyslím, žeby to malo nejaký praktický význam.
.
Ostáva mi vyriešiť otázku života Transaction ako takého (vytvorenie a zničenie). Tie v DataModule ponechám, lebo ich potrebujem v čase programovania - živé prepojenie DB komponentov s DB.
Teraz mám úlohu uviesť, najprv teoreticky, do praxe výrok "transakciu vytvorím pred začiatkom cyklu". Ako vidieť z môjho kódu, teraz ich priraďujem v NewQry. Potrebujem to premiestniť do OpenQry. Tým pádom to musím hrať na premennú/é, kde si tú transakciu uložím. Má to výhody:
Zas som si pokecal, ale to mi pomáha vo vyjasnení problému. A niekedy dostanem veľmi dobré rady. Nie všetky výlevy duše tu uverejňujem.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 21-10-2020, 22:19:44
Citace
My jsme v dobach, kdy tam bylo tupe prochazeni cyklu jeste pred generiky a unicodifikaci Delphi doplnili index na jmena a jestli si to pamatuju, tak se to zrychlilo 4x - ta efektivita zalezi na nejakem strednim poctu poctu poli v aplikaci a co se s temi datasety dela.
Ja som raz, už zo zúfalstva, pridal do join prepojenie dvoch tabuliek, ktoré už boli prepojené nepriamo. Čas vykonania sa mi skrátil aspoň o dva rády. Dosť som na to čumel a zároveň som sa neskutočne potešil.
Tie hash-ovacie funkcie sú vo vzťahu k indexom?
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: pf1957 22-10-2020, 07:33:33
Tie hash-ovacie funkcie sú vo vzťahu k indexom?
Tento typ hashovacich funkci (napr. narozdil od el. podepisovani dat) slouzi k namapovani hodnoty do klice, ktery slouzi primo jako index do datove struktury napr. Data[hashkey] a tim se obchazi hledani, at uz jakymkoli algoritmem a az na pripadne kolize klicu se nic neprohledava. Takze rychlostne je vypocetu hashe + cas na reseni kolizi vs. cas na vyhledani dat.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: pf1957 22-10-2020, 07:36:10
Transakce ztrácí smysl, pokud ukládáš jeden záznam do tabulky - tam víš, jestli se uložil nebo ne.
Kdyz vezmeme v uvahu izolaci, tak vv multitaskingovem/viceuzivatelskem prostredi maji vyznam i tak.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jirka 22-10-2020, 10:39:23
Vidím, že ku kódu nemáš pripomienku, čo ma teší. 

Aby nedošlo k omylu.  Já se k němu pouze nevyjádřil ;)
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 22-10-2020, 11:39:52
To si ma nemohol nechať v mojej blaženej nevedomosti?
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jan Fiala 23-10-2020, 11:51:11
Transakce ztrácí smysl, pokud ukládáš jeden záznam do tabulky - tam víš, jestli se uložil nebo ne.
Kdyz vezmeme v uvahu izolaci, tak vv multitaskingovem/viceuzivatelskem prostredi maji vyznam i tak.

Bral jsem to na případ tabulky a editace jednoho záznamu - edit/post. Tam se právě projeví negativum - transakce se ti otevře při edit a ukončí až při post, takže přijdeš o to, že by měla být transakce co nejkratší.
Ale trvám na svém názoru, že ve víceuživatelském prostředí použití Table proti SQL nemají co dělat. Tabulku (memory) můžu použít jako dočasné úložiště dat jako alternativu třeba k objectlistu nebo jako podklad pro někoho, kdo se nedokáže rozloučit s dbAware komponentami, podklad pro cxGrid (QuantumGrid) atd.
Na konec vygeneruju ze změněných záznamů update, ten v transakci provedu a transakci ukončím.
Jako alternativa (lepší) je poslat změněné   nové záznamy do pomocné tabulky na SQL, následně zavolat uloženou proceduru, která to zpracuje, vše ověří a v transakci zapíše do několika tabulek.
Je s tím ale mnohem víc práce než to jen "naklikat".
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 23-10-2020, 12:41:31
Citace
Tabulku (memory) můžu použít jako dočasné úložiště dat jako alternativu třeba k objectlistu nebo jako podklad pro někoho, kdo se nedokáže rozloučit s dbAware komponentami,
Citace
Je s tím ale mnohem víc práce než to jen "naklikat".
To je u mňa dosť podstatný problém
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: pf1957 23-10-2020, 12:59:20
Ale trvám na svém názoru, že ve víceuživatelském prostředí použití Table proti SQL nemají co dělat.
Naprosty souhlas. Nikde jsem to nevidel pouzit. Kdyz uz prisla bida na kozaky, tak jsem jako docela rozumne reseni videl CDS a load/save v rucne rizenych txn.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 23-10-2020, 13:26:48
Tak som si zbežne pozrel TFDMemTable a príslušenstvo. Nevyzerá to zle. Mám funkciu na generovanie SQL textu Into or Update z tabuľky.
Jediný väčší/prácnejší problém vidím v naplnení parametrov správnymi hodnotami. Neviem či sa to deje automaticky, ak použijem MemTable + DataSource.
Môžem tam, kde mám TFDTable bez problémov použiť/zmeniť na TFDMemTable?
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jan Fiala 25-10-2020, 12:00:37
Memory tabulka se používá třeba tak, že provedeš dotaz (Query) a data nakopíruješ do memory tabulky - obvykle funkce memorytabulka.CopyData(Query, [...]), které předáš Query a parametry co vše se má převzít - struktura, data atd. Pak query zavřeš a pracuješ offline do doby, než budeš chtít změny zapsat.
Pokud chceš občerstvit data, pak si zapamatuješ pozici (abys zůstal v gridu na místě), provedeš znovu načtení dat - query, CopyData a vrácení pozice. Tohle pohodlně zapouzdříš do volání obecné funkce a nemusíš se o to starat.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Stanislav Hruška 25-10-2020, 12:18:33
Hm, v návode som čosi čítal a Queries pre načítanie, update a insert. To si tu FierDAC nemôže vytvoriť automaticky, pretože nepozná tabuľku. Alebo si to pamätám zle.
To kopírovanie údajov dávajú všade. S tým by nemal byť problém.
Zmeny sa zapisujú .Post? Nie je potrebná predtým žiadna príprava?
Pozíciu si musím zapamätať kvôli tabuľke. Čiže PK záznamu. Nie kvôli mriežke, pretože nepoužíva DBGrid.
Ako funguje Locate()? Predpokladám, že si to si musím urobiť sám, nakoľko MemTable nepozná tabuľku.
.
Ďakujem za návod.
Název: Re:Table.Delete OK, Table.Post NIE
Přispěvatel: Jan Fiala 27-10-2020, 16:56:37
Ako funguje Locate()? Predpokladám, že si to si musím urobiť sám, nakoľko MemTable nepozná tabuľku.

Locate provádíš přímo nad memory tabulkou její metodou MemTable.Locate. Nebo možná nerozumím, co jsi chtěl říct tím, že memtable nezná tabulku...
Stejně tak si tam můžeš v případě potřeby vytvářet indexy, nová pole atd.

Pokud to chceš používat pro editaci, je třeba přidat další sloupec, do něj si zachytit změny (insert/update/delete) a při zápisu se s tím poprat a pomocí SQL příkazů to zapsat na server. V případě větších změn to celé přenést do pomocné tabulky na serveru a uloženou procedurou zapsat (transakce až v uložené proceduře těsně před vlastním zápisem).
Ale je to úplně jiný styl práce, než jak jsi pracoval dosud.