Autor Téma: Kde jsou data ?  (Přečteno 1742 krát)

rustymattock

  • Host
Kde jsou data ?
« kdy: 17-02-2018, 02:34:12 »
zdravím.
popsaný problém se objeví jen sporadicky a nemám na něj ani nepravděpodobnou hypotézu. Snad někdo, kdo s MSSQL pracuje často...

Do tabulky vložím několik záznamů (každý rádově desítky bajtů).
Když dám pak SELECT * FROM , tak ke stávajícím řádkům je přidán pouze první z přidaných záznamů (i když dám SELECT třeba 5x po sobě).
Když ten první z přidaných záznamů smažu, tak se v databázi objeví druhý přidaný... atd.
Takhle jsem si s tim hrál snad 20 minut v kuse a ze všech přidaných záznamů byl v databáze vždy jen 1 (záznamy z předešlých hodin a dnů ovšem vždy všechny).

...když jsem na to kouknul na druhý den, už v databáze byly všechny data, které jsem při testování přidával a aplikace pracovala s databází tak jak má.

Z toho je zřejmé, že INSERT INTO proběhl úspěšně. Ale kde ty data jsou, než se jim uráčí ukázat se v databáze ??
Pravděpodobnější samozřejmě nejspíš bude, že chyba je na straně kódu aplikace, ale opravdu se nechytám, co takové chování může způsobit, tudiž ani co mám hledat.

Poznámka: tabulka se testuje, takže má v tuto chvíli směšných 40-50 řádků (celkově ne víc, než 2-3 Kb). Přistupuje se k ní ze 3 PC, stejnou aplikací a nikdy ne najednou.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3460
  • Karma: 35
    • Verze Delphi: XE7 professional
Re:Kde jsou data ?
« Odpověď #1 kdy: 17-02-2018, 08:56:41 »
Len tak naslepo:
  • SQL.Transaction.Commit - veľmi by som sa čudoval, keby si to nemal
  • MS SQL vôbec nepoznám. Nechýba Ti tam niekde niečo ako MyTable.Refresh?
Aby si dostal odpoveď, tak doplň základné údaje:
  • ktoré komponenty používaš na prácu s DB
  • základné nastavenia Connection. Asi tam existuje niečo ako urob to všetko okamžite/až sa ti uráči, nech zmeny vidia okamžite všetci a pod.
  • nejakú kompletnú jednoduchú ukážku kódu vkladania záznamov

Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2231
  • Karma: 117
    • Verze Delphi: D2007, XE3, DX10
Re:Kde jsou data ?
« Odpověď #2 kdy: 17-02-2018, 08:56:53 »
Excellent
Rated 1 time
Z toho je zřejmé, že INSERT INTO proběhl úspěšně. Ale kde ty data jsou, než se jim uráčí ukázat se v databáze ??
Pravděpodobnější samozřejmě nejspíš bude, že chyba je na straně kódu aplikace,
Ta data jsou pravdepodobne v DB a viditelna budou, az se tvoje aplikace uraci commitnout transakci. S DB se zpravidla pracuje pod nejakou transakci, nejbezneji typu ReadCommitted (na ruznych RDBMS se to muze jmenovat ruzne), jejiz zakladni vlastnosti je, ze na data vlozena v ramci teto transakce je videt jen z teto transakce a vsichni ostatni ta data vidi az po commitnuti transakce. To dava sanci napr. strhnout penize z jednoho uctu a pripsat je na ucet jiny. Ostatni vidi stav pred prevodem a po prevodu, nic mezi tim, stejne jako to dava sanci stornovat vsechny DB operace od zahajen v pripade, ze neco selze. Rika se tomu atomicita. Schematicky se s DB pracuje takto:
Kód: [Vybrat]
Transaction.Start;
try
  // Vsechny tvoje logicky spojene (atomicke) DB operace
  delete ...
  insert ....
  insert ....
  select ...
  insert ...
  ...
  Transaction.Commit;
except
  Transaction.Rollback;
  raise;
end

rustymattock

  • Host
Re:Kde jsou data ?
« Odpověď #3 kdy: 17-02-2018, 15:26:38 »
Pro doplnění: používám FireDAC

a SQL dotazy jsou zapsány takhle (obdobně pro všechny operace):
procedure DeleteFromBox_comp(ARow:integer);
begin
  DataModule1.FDQuery.SQL.Clear;
  DataModule1.FDQuery.SQL.Text:='DELETE FROM box_comp WHERE A2C=:A2C AND Line=:Line AND Count=:Count AND MyStamp=:TimeStamp';
  DataModule1.FDQuery.ParamByName('A2C').AsString:=BoxComp[ARow].A2C;
  DataModule1.FDQuery.ParamByName('Line').AsString:=CompList.MyLine;
  DataModule1.FDQuery.ParamByName('Count').AsInteger:=BoxComp[ARow].Count;
  DataModule1.FDQuery.ParamByName('TimeStamp').AsFloat:=BoxComp[ARow].MyStamp;
  try
    DataModule1.FDQuery.ExecSQL;
  except
    CompList.MyErrorMessage:='Odebrání materiálu ('+BoxComp[ARow].A2C+') z databáze se nezdařil(box_comp)';
    exit;
  end;
end;

O Commit slyším poprvé. Takže to bude asi ono.  Dle Googlu předpokládám, že za DataModule1.FDQuery.ExecSQL, doplním DataModule1.FDConnection.Commit. Ano ?
Stejně nerozumím proč to v 95% jede bez problémů, jestli tam něco chybí.

Offline miroB

  • Hrdina
  • ****
  • Příspěvků: 374
  • Karma: 14
    • Verze Delphi: D1,2,3,4,7,2005,2009, XE8,S,B,T10.2.2 Pro
Re:Kde jsou data ?
« Odpověď #4 kdy: 17-02-2018, 16:06:04 »
..
  DataModule1.FDQuery.SQL.Clear;
  DataModule1.FDQuery.SQL.Text:='DELETE FROM box_comp WHERE A2C=:A2C AND Line=:Line AND Count=:Count AND MyStamp=:TimeStamp';
  DataModule1.FDQuery.ParamByName('A2C').AsString:=BoxComp[ARow].A2C;
  DataModule1.FDQuery.ParamByName('Line').AsString:=CompList.MyLine;
  DataModule1.FDQuery.ParamByName('Count').AsInteger:=BoxComp[ARow].Count;
  DataModule1.FDQuery.ParamByName('TimeStamp').AsFloat:=BoxComp[ARow].MyStamp;
..

Chyba moze byt v tom, ze  DataModule1.FDQuery.Params.. nemaju urceny vopred typ parametrov.
Query nie je "Prepared" a v podstate neprijma ziadne hodnoty, aj ked sa zda, ze ano..

Klikni si v "Object Inspector" na "DataModule1.FDQuery"
a tam
Params (TFDParams)
Rozbal tie 4 parametre a pridaj im hodnoty DataType resp FDDataType
Potom skus znovu a dufam ti to cele uz pojde.
Vid aj obrazok

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3460
  • Karma: 35
    • Verze Delphi: XE7 professional
Re:Kde jsou data ?
« Odpověď #5 kdy: 17-02-2018, 16:15:12 »
Citace
O Commit slyším poprvé. Takže to bude asi ono. Dle Googlu předpokládám, že za DataModule1.FDQuery.ExecSQL, doplním DataModule1.FDConnection.Commit. Ano?
Stejně nerozumím proč to v 95% jede bez problémů, jestli tam něco chybí.
Pozri si nastavenia Connection a Transaction. Určite máš niekde nastavený Autocommit := True; Pre operácie, ktoré menia údaje sa zásadne nastavuje na False. Prejdi si diskusiu FireBird. Tam mi to vysvetľovali.
Kód: SQL [Vybrat]
  1. PROCEDURE DeleteFromBox_comp(ARow: INTEGER);
  2. var
  3.   Query: TFDQuery;  // Bude TO čitateľnejšie
  4. BEGIN
  5.   Query := DataModule1.FDQuery;
  6.   Query.SQL.Text:='DELETE FROM box_comp WHERE A2C = :A2C AND Line = :Line AND Count = :Count AND MyStamp = :TimeStamp';
  7.   Query.ParamByName('A2C').AsString := BoxComp[ARow].A2C;
  8.   Query.ParamByName('Line').AsString := CompList.MyLine;
  9.   Query.ParamByName('Count').AsInteger := BoxComp[ARow].COUNT;
  10.   Query.ParamByName('TimeStamp').AsFloat := BoxComp[ARow].MyStamp;
  11.  
  12.   try
  13.     Query.TRANSACTION.StartTransaction;
  14.     Query.ExecSQL;
  15.     Query.TRANSACTION.Commit;
  16.   EXCEPT
  17.     CompList.MyErrorMessage := 'Odebrání materiálu (' + BoxComp[ARow].A2C + ') z databáze se nezdařil(box_comp)';
  18.     raise;
  19.   END;
  20. END;
Ach to formátovanie zdrojov.
« Poslední změna: 17-02-2018, 16:18:18 od Stanislav Hruška »
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3460
  • Karma: 35
    • Verze Delphi: XE7 professional
Re:Kde jsou data ?
« Odpověď #6 kdy: 17-02-2018, 16:17:04 »
Citace
Chyba moze byt v tom, ze  DataModule1.FDQuery.Params.. nemaju urceny vopred typ parametrov.
To som ešte v živote nenastavoval a všetko mi beží :)
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1123
  • Karma: 52
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Kde jsou data ?
« Odpověď #7 kdy: 17-02-2018, 16:24:25 »
Chyba moze byt v tom, ze  DataModule1.FDQuery.Params.. nemaju urceny vopred typ parametrov.

FireDAC provadi implicitni konverzi pri predavani hodnot parametru DBMS. A v pripade ze si pripravis v design time kolekci parametru, v runtime pak nesmis zmenit SQL.Text, jinak je po ni (coz se da i vypnout, ale osobne bych to nedelal).

Pozri si nastavenia Connection a Transaction. Určite máš niekde nastavený Autocommit := True; Pre operácie, ktoré menia údaje sa zásadne nastavuje na False.

Pokud spoustis jeden prikaz jako je i tento priklad, neni duvod autocommit nepouzit. A FireDAC je inteligentni natolik, ze pokud explicitne nastartujes transakci, implicitni nevytvori (takze tim zavolanim StartTransaction de-facto ignorujes nastaveni AutoCommit). S tovarnim nastavenim komponent dojde v uvedenem kodu k nastartovani a v pripade uspesneho spusteni prikazu i commitu implicitni transakce. P.S. chybi Ti tam Rollback.



"...když jsem na to kouknul na druhý den" zni jako kdyby FireDAC provedl commit pri odpojeni spojeni s DBMS (DisconnectAction == xdCommit), cili tam mozna skutecne nekde visi necommitnuta transakce. Ale tady muzeme jen hadat.

Jednoduchym pravidlem muze byt nechat TX auto property jak jsou v tovarnim nastaveni a pri potrebe pouzit transakce je explicitne nastartovat, commitnout prip. rollbacknout. Napr.:

Kód: Delphi [Vybrat]
  1. FDQuery1.Transaction.StartTransaction;
  2. try
  3.   FDQuery1.ExecSQL('...');
  4.   FDQuery1.ExecSQL('...');
  5.   FDQuery1.Transaction.Commit;
  6. except
  7.   FDQuery1.Transaction.Rollback;
  8.   raise;
  9. end;
« Poslední změna: 17-02-2018, 16:39:21 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 Stanislav Hruška

  • Padawan
  • ******
  • Příspěvků: 3460
  • Karma: 35
    • Verze Delphi: XE7 professional
Re:Kde jsou data ?
« Odpověď #8 kdy: 17-02-2018, 16:39:27 »
Ešte poznámka. Všetky príkazy spracuj v jednej dávke!
Delphi XE7, FireBird
Expert na kladenie nejasne formulovaných otázok.

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2231
  • Karma: 117
    • Verze Delphi: D2007, XE3, DX10
Re:Kde jsou data ?
« Odpověď #9 kdy: 17-02-2018, 16:41:40 »
Pokud spoustis jeden prikaz jako je i tento priklad, neni duvod autocommit nepouzit.
Je, protoze pak vznikaji paskvily, ktere v 95 % funguji, jak pise OP. Osobne bych rezim AutoCommit zcela zrusil: slusne napsany soft bude pouzivat vsude jeden zpusob rizeni transakce a protoze AutoCommit je pro ten ucel k nicemu, je jasne, jak to delat ;-)

Citace
A FireDAC je inteligentni natolik, ze pokud explicitne nastartujes transakci, implicitni nevytvori (takze tim zavolanim StartTransaction
Vetsina DB connectivit pri explicitnim nastartovani transakce lokalne shodi  AutoCommit, ale je lepsi pri kazdem vytvoreni instance transakce ho explicitne priradit na False (treba pomoci interposed tridy, ktera to v konstruktoru shodi jednou pro celou aplikaci), protoze tim davam jasne najevo vsem ctenarum kodu, ze vim co delam a transakce si budu vsude ridit sam.

Citace
P.S. chybi Ti tam Rollback.
Nejen, Ma-li byt rizeni transakce ciste, musi byt StartTransaction pred try, protoze kdyz se nepovede zahajit transakci, tak to nesmi spadnout na Rollback, ale tu chybu je treba odchytit v jinem (vnejsim) scope try-except.
« Poslední změna: 17-02-2018, 16:48:24 od pf1957 »

Offline Delfin

  • Guru
  • *****
  • Příspěvků: 1123
  • Karma: 52
  • SW konzultant
    • Verze Delphi: 2009, Tokyo
Re:Kde jsou data ?
« Odpověď #10 kdy: 17-02-2018, 16:47:32 »
Pokud spoustis jeden prikaz jako je i tento priklad, neni duvod autocommit nepouzit.
Je, protoze pak vznikaji paskvily, ktere v 95 % funguji, jak pise OP.

Nevznikaji, protoze FireDAC za Tebe pouzije implicitni transakci. Je to uplne to same co bys udelal explicitne v kodu. No a pokud zprasis rizeni transakci, je uz celkem jedno zda Ti pak nepujde commitnout volani ExecSQL bez explicitniho rizeni nebo s nim. Rozhozene to budes mit v obou pripadech.

Pokud mas AutoCommit zapnuty, neni de-facto rozdil mezi implicitnim rizenim:

Kód: Delphi [Vybrat]
  1. FDQuery1.ExecSQL('...');

A explicitnim:

Kód: Delphi [Vybrat]
  1. FDQuery1.Transaction.StartTransaction;
  2. try
  3.   FDQuery1.ExecSQL('...');
  4.   FDQuery1.Transaction.Commit;
  5. except
  6.   FDQuery1.Transaction.Rollback;
  7.   raise;
  8. end;
« Poslední změna: 17-02-2018, 16:55:07 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 pf1957

  • Padawan
  • ******
  • Příspěvků: 2231
  • Karma: 117
    • Verze Delphi: D2007, XE3, DX10
Re:Kde jsou data ?
« Odpověď #11 kdy: 17-02-2018, 16:55:20 »
Nevznikaji, protoze FireDAC za Tebe pouzije implicitni transakci. Je to uplne to same co bys udelal explicitne v kodu.
To plati jen pro jeden izolovany ExecSQL. Ale lidi jako OP, kteri nikdy neslyseli o Commit, nenapadne, ze kdyz si pridaji jeste dalsi ExeSQL, ze kazdy pobezi v jine transakci a ze to nebude ACID.

rustymattock

  • Host
Re:Kde jsou data ?
« Odpověď #12 kdy: 17-02-2018, 17:01:11 »
Tak vám všem děkuji.
Doplním tam dle doporučení Commit i Rollback. Snad to opravdu bylo ono.

P.S: k čemu je Rollback(když už čtu, že tam musí být) ?
...a ExecSQL je v kódu opravdu víc (7 nebo 8)

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2231
  • Karma: 117
    • Verze Delphi: D2007, XE3, DX10
Re:Kde jsou data ?
« Odpověď #13 kdy: 17-02-2018, 17:04:39 »
P.S: k čemu je Rollback(když už čtu, že tam musí být) ?
Google negoogluje? Heslovite treba http://nb.vse.cz/~palovska/bivs/DBII_2_advancedSQL.pdf

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2231
  • Karma: 117
    • Verze Delphi: D2007, XE3, DX10
Re:Kde jsou data ?
« Odpověď #14 kdy: 17-02-2018, 17:11:06 »
Snad to opravdu bylo ono.
Tezko rict, ale obecne plati, ze s transakcemi a thready je treba pracovat cistym zpusobem, protoze jinak mohou vznikat tezko laditelne/simulovatelne/lokalizovatelne chyby a je treba udelat maximum pro to, aby tato kategorie chyb pokud mozno vubec nevznikla. Samozrejme to zacina u teorie...

 

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

Upozornění: do tohoto tématu bylo naposledy přispěno před 120 dny.
Zvažte prosím založení nového tématu.

Jméno: E-mail:
Ověření:
Kolik je šest plus čtyři (slovem):