Autor Téma: Ako riešiť INSERT z viacerých vlákien  (Přečteno 268 krát)

Offline František

  • Guru
  • *****
  • Příspěvků: 510
  • Karma: 6
    • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
Ako riešiť INSERT z viacerých vlákien
« kdy: 04-09-2019, 23:19:46 »
mám teraz INSERT poriešený z každého vlákna separátne (pomocou FD connection pooling do Firebirdu - pre každé vlákno nový objekt CP) ... ale keď to spustím ... zhrkoce mi to za nejaky cas.... a to tak že to nezvláda ani debuger

napadlo mi, či by to nebolo lepšie súkať do nejakého (akého?) buffra a odtiaľ to v ďalšom vlákne INSERTOVAT do DB? poradíte prosím, ako to zosnovať? alebo je nejaké elegantnejšie riešenie?

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2346
  • Karma: 102
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • O Delphi v češtině
Re:Ako riešiť INSERT z viacerých vlákien
« Odpověď #1 kdy: 05-09-2019, 08:10:51 »
FireDac je threadsafe vcetne connection poolu, vytvaris ty objekty pro query ve vlakne?
Embarcadero MVP - Czech republic

Offline pepak

  • Guru
  • *****
  • Příspěvků: 1432
  • Karma: 34
    • Pepak.net
Re:Ako riešiť INSERT z viacerých vlákien
« Odpověď #2 kdy: 05-09-2019, 08:12:33 »
A vytváříš jenom objekty pro query a nic jiného? Speciálně je krajně nevhodné vytvářet datamoduly, ty thread-safe nejsou.

Offline František

  • Guru
  • *****
  • Příspěvků: 510
  • Karma: 6
    • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
Re:Ako riešiť INSERT z viacerých vlákien
« Odpověď #3 kdy: 05-09-2019, 08:36:28 »
najskor si vytvorim conection pool a zadefinujem DB

datasety nemam len TFDQuery a TFDScript

postup:
inicializacia vlakna vytvori formular s progres barom, injektne ho na panel, stiahne subor - potialto to prebehne aj 10 vlakien ok..
ked je subor stiahnuty, spusti sa parsing a zapis do db

pojednom je to OK - prebehne ako ma
ale ked spustim viac sucastne, tak v neurcitej situacii sa to zastavi (progress bar pre kazde vlakno to indikuje) ... a do 10s vyhodi chybu aj debuger



Offline František

  • Guru
  • *****
  • Příspěvků: 510
  • Karma: 6
    • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
Re:Ako riešiť INSERT z viacerých vlákien
« Odpověď #4 kdy: 05-09-2019, 08:41:24 »
pouzivam na to AnonymousThread a ked vlakno vykona co ma (v TDictionary si drzim info o objekte), tak zmeni priznak ktory testujem Timerom kazdu sekundu a tam aj objekty uvolnujem

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2346
  • Karma: 102
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • O Delphi v češtině
Re:Ako riešiť INSERT z viacerých vlákien
« Odpověď #5 kdy: 05-09-2019, 09:22:11 »
najskor si vytvorim conection pool a zadefinujem DB

datasety nemam len TFDQuery a TFDScript

postup:
inicializacia vlakna vytvori formular s progres barom, injektne ho na panel, stiahne subor - potialto to prebehne aj 10 vlakien ok..
ked je subor stiahnuty, spusti sa parsing a zapis do db

pojednom je to OK - prebehne ako ma
ale ked spustim viac sucastne, tak v neurcitej situacii sa to zastavi (progress bar pre kazde vlakno to indikuje) ... a do 10s vyhodi chybu aj debuger

Podle mne anonymni thread nezajisti synchronizaci s hlavnim vlaknem, takze cokoliv co pristupuje k prvkum UI (tj. i nastavovani pozice progressbaru) musi byt volano pres synchronizaci. Podle mne s tvojim problemem nema firedac nic spolecneho.

A to s tim timerem taky nic moc. Tvoje reseni se mi zda moc komplikovane, navic "tak zmeni priznak ktory testujem", nemuze se stat ze ten priznak je soucasti nejakeho objektu, ktery po ukonceni vlakna je uvolnen.


Embarcadero MVP - Czech republic

Offline František

  • Guru
  • *****
  • Příspěvků: 510
  • Karma: 6
    • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
Re:Ako riešiť INSERT z viacerých vlákien
« Odpověď #6 kdy: 05-09-2019, 10:01:18 »
A to s tim timerem taky nic moc. Tvoje reseni se mi zda moc komplikovane, navic "tak zmeni priznak ktory testujem", nemuze se stat ze ten priznak je soucasti nejakeho objektu, ktery po ukonceni vlakna je uvolnen.

nie to sa nestane, lebo informacia k objektu je vytvarana mimo vlakna a ako som spominal je v TDictionary kde ju aj po dokonceni vlakna timerom uvolnujem...

ale vobec sa nebranim inemu rieseniu,

asi som to zle popisal.. ono je to tak ze anonym vlakno je vytvorene az v ramci objektu - vlakno skonci a informuje v ramci objektu o svojom ukonceni .. a az potom uvolnim aj objekt tim timerom

problem je ze vlakno neskoci (teda mozno aj ano ale nejakym errorom)a objekt sa ale neuvolni, lebo ho o tom vlakno nestihlo informovat ..
« Poslední změna: 05-09-2019, 10:03:24 od František »

Offline František

  • Guru
  • *****
  • Příspěvků: 510
  • Karma: 6
    • Verze Delphi: primárne v XE5, občas 10.2.3 comunity
Re:Ako riešiť INSERT z viacerých vlákien
« Odpověď #7 kdy: 06-09-2019, 08:55:43 »
vedel by mi niekto popísať správny postup?

Offline pf1957

  • Padawan
  • ******
  • Příspěvků: 2593
  • Karma: 133
    • Verze Delphi: D2007, XE3, DX10
Re:Ako riešiť INSERT z viacerých vlákien
« Odpověď #8 kdy: 06-09-2019, 13:31:10 »
vedel by mi niekto popísať správny postup?
Pokud je rozlozeni operaci rozumne a operace netrva dlouho, tak musi stacit standardni pristup: kazdy thread vlastni Query a vlastni Write transakci, kterou si bude explicitne ridit. U nekterych RDBMS (napr. MSSQL) jeste vlastni connection, to ale neni pripad FireBirdu.

A je treba radne osetrit pripadne chyby a testovat vysledky operaci, aby se presne vedelo, co se ti tam deje.

Offline Radek Červinka

  • Administrátoři
  • Padawan
  • *****
  • Příspěvků: 2346
  • Karma: 102
    • Verze Delphi: D5,D2007, DXE, DXE2 + 2 poslední (Tokyo)
    • O Delphi v češtině
Re:Ako riešiť INSERT z viacerých vlákien
« Odpověď #9 kdy: 06-09-2019, 13:55:15 »

...
a do 10s vyhodi chybu aj debuger


Dobrý začátek je říct co přesně je to za chybu, ideálně ukázat callstack. Omlouvam se, ale moje křištálová koule je momentálně v opravě.
Embarcadero MVP - Czech republic