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.“