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

Upozornění: Tohle vlákno je hodně staré a informace nemusí být platné pro současné Nette.
arron
Člen | 464
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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
+
0
-

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

arron
Člen | 464
+
0
-

Diky za nazory:-)