Nette a Doctrine 2 – kdy volat $entityManager->flush()?

- arron
- Člen | 464
Prijde mi nesmysl volat tuto metodu po kazdem volani modelu. Ale na konci
aplikace (tedy po $application->run()) uz je to zase asi pozde,
protoze flush() muze vyhodit vyjimku, ktera za urcitych okolnosti
muze byt osetrena a je treba znovu zobrazit napriklad formular s predvyplnenymi
daty ci neco takoveho.
Mate s tim nekdo nejakou zkusenost nebo nazor?
Diky moc.

- Panda
- Člen | 569
Po každé sadě operací, které mění databázi a souvisejí spolu –
například na konci onSubmit handleru formuláře, nezávisle na
tom, jestli vytváří/upravuje 1 entitu, nebo 10.
Jakékoliv jiné volání je nesmysl, protože pak se mohou do jedné transakce dostat operace, které spolu na sobě vůbec nezávisí (a to je samozřejmě špatně).

- arron
- Člen | 464
Jo, cim vic nad tim premyslim, tim vic mam pocit, ze mas pravdu :-)
Nicmene me trapi dve veci:
- tezko se to bude delat automaticky…resp. kdo tento proces spusti? Handler
onSubmit? Toho by to nemelo zajimat. Tak by to mel asi spustit model? Jenze ten nevi, kdy to ma udelat. A nebo k tomu pristupuju uplne spatne? - jestli jsem to vsechno spravne pochopil, tak operace flush() je pomerne dost draha, takze bych mel tendenci ji volat jenom jednou…

- Patrik Votoček
- Člen | 2221
automatizovaně není úplně super… lepší je to pustit růčo nakonci onSubmit callbacku… Já mám přeba v presenterech a controlech udělanou zkratku že zavolám $this->em->flush(); a je to…

- Panda
- Člen | 569
A kolik zápisů při jednom požadavku běžně provádíš? Já teda
vždycky nejvýše jeden – odeslání formuláře, volání handleru…
A pro to je ruční volání nejlepší, protože programátor by měl nejlépe
vědet, kdy je potřeba flush() volat a kdy ne. Nějaká automatika
by taky ten flush v některých případech mohla volat úplně zbytečně
(což je ještě horší).
Ano, ta funkce je poměrně náročná, defaultně musí projet všechny entity a zjistit, co všechno se v nich změnilo. Pokud máš takový strach o výkon, podívej se na Change Tracking Policies v dokumentaci k Doctrine 2.
Volání flush() je případ, kdy by měl zvítězit rozum nad
honbou za co nejvyšším výkonem. Pokud máš v jednom požadavku dvě
naprosto nezávislé operace, které modifikují datbázi, zavolej
flush() dvakrát, pro každou z nich. Je skutečně
důležitější obě operace od sebe oddělit, než se pokoušet zvýšit si
výkon jediným voláním. Dotazy se totiž automaticky uzavírají do transakce
a pokud některý selže, provede se rollback. Pokud tedy dojde k chybě
v dotazu z druhé operace, přijdeš i o data z první a už se to
nedozvíš.
„Premature optimization is the root of all evil.“