Upgrade to Pro — share decks privately, control downloads, hide ads and more …

Doctrine Internals. UnitOfWork

Doctrine Internals. UnitOfWork

Andrey Yatsenco

April 28, 2016
Tweet

More Decks by Andrey Yatsenco

Other Decks in Programming

Transcript

  1. Presentation title here About me https://www.facebook.com/yatsenco https://github.com/anyt about me… Andrey

    Yatsenco • PHP Developer at Oro Inc. • 3 years with Symfony • 6 years with PHP
  2. Presentation title here Doctrine Internals. UnitOfWork Introduction • Doctrine is

    the bottleneck for many apps • You know how UnitOfWork is working, you know how doctrine works
  3. Presentation title here Doctrine Internals. UnitOfWork UnitOfWork track objects changes

    and commit them transactionally to the Database. Now you don’t manage object loading from the DataBase. UOW do.
  4. Presentation title here Doctrine Internals. UnitOfWork UOW use IdentityMap to

    track objects changes and to avoid server round trip It simple two level array storage • First level keys are ClassNames • Second level keys are object IDs.
  5. Presentation title here Doctrine Internals. UnitOfWork Doctrine EntityManager is like

    all-in-one decorator on • Repository • UnitOfWork • MetadataFactory • ProxyFactory • etc.
  6. Presentation title here Doctrine Internals. UnitOfWork EntityManager -> EntityRepository •

    find • findOneBy • findAll • customFindQueryWithHidration • etc.
  7. Presentation title here Doctrine Internals. UnitOfWork Doctrine flow • 1)

    Fetch entities from the database or create new and persist ‘em (Repo|UOW) • 2) Update some of entities directly or using wrapper like Form (uses PropertyAccess) • Remove some, if needed (Forms etc.) • 3) EM->flush() changes (UOW)
  8. Presentation title here Doctrine Internals. UnitOfWork 1) Fetching entities from

    the DB • One entity: ◦ find ◦ findOneBy • Several entities: ◦ Lazy/Eager loading ◦ Find partial
  9. Presentation title here Doctrine Internals. UnitOfWork 1) Persist • Can

    be omitted if you fetched entities from doctrine • Required only for newly created entities
  10. Presentation title here Doctrine Internals. UnitOfWork 2) Update Object changes

    outside Doctrine. • Direct changes • Forms (PropertyAccessor) • etc.
  11. Presentation title here Doctrine Internals. UnitOfWork 3) Flush Flow •

    Open DB transaction • Complute change-sets for update • Iterate over scheduled inserts, updates, deletes • Delegate to entity persister SQL generation and execution • Clear UOW on success • Close DB transaction
  12. Presentation title here Doctrine Internals. UnitOfWork Fetch Repo-> find|refresh|getReference|etc. •

    (optional) sync data with DB • Events::loadClassMetadata ◦ If ! Events:onClassMetadataNotFound • hydrate • Events:postLoad
  13. Presentation title here Doctrine Internals. UnitOfWork Persist • Events:prePersist •

    Entity ID isn’t exist at this time in most cases • UOW->scheduleForInsert($entity)
  14. Presentation title here Doctrine Internals. UnitOfWork Flush (1) • Events::preFlush

    ◦ $em->flush() can be called safely • compute insert|update|delete changesets • If !changes ◦ Events::onFlush ◦ Events::postFlush ◦ return
  15. Presentation title here Doctrine Internals. UnitOfWork Flush (2) • Events::onFlush

    ◦ UOW->getScheduledEntityInsertions() ◦ UOW->getScheduledEntityUpdates() ◦ UOW->getScheduledEntityDeletions() ◦ $em->persist() && UOW- >computeChangeSet() • connection->beginTransaction
  16. Presentation title here Doctrine Internals. UnitOfWork Flush (3) • Inserts

    ◦ Persister->insert($entity) ◦ Events::postPersist ▪ entity can’t be updated directly anymore ▪ UOW->scheduleExtraUpdate($entity, array $changeset)
  17. Presentation title here Doctrine Internals. UnitOfWork Flush (4) • Updates

    ◦ Events::preUpdate ▪ Entity can’t be updated directly, update changeset using PreUpdateEventArgs ▪ Relations changes not tracked too ◦ UOW->recomputeSingleEntityChangeSet($class, $entity) ◦ Persister->update($entity) ◦ Events::postUpdate ▪ Entity can’t be updated directly anymore ▪ UOW->scheduleExtraUpdate($entity, array $changeset) • UOW->executeExtraUpdates()
  18. Presentation title here Doctrine Internals. UnitOfWork Flush (5) • Deletions

    ◦ Persister->delete($entity) ◦ Events::postRemove ▪ nothing to update here
  19. Presentation title here Doctrine Internals. UnitOfWork Flush (6) • connection->commit()

    • Events::postFlush ◦ Never call $em->flush() here • UOW->clear(); ◦ Events::onClear • in case of errors ◦ connection->rollback() That’s it.
  20. Presentation title here Doctrine Internals. UnitOfWork Let’s talk a little

    bit about performance and how to speed-up doctrine
  21. Presentation title here Doctrine Internals. UnitOfWork How to speed-up doctrine

    • Control lazy-loading ◦ Never eager load ◦ Write select queries with joins to needed
  22. Presentation title here Doctrine Internals. UnitOfWork How to speed-up doctrine

    • Hydrate less ◦ arrays instead of objects when you don’t need them or performance is important
  23. Presentation title here Doctrine Internals. UnitOfWork How to speed-up doctrine

    • Make flush cheaper ◦ Mark entities as readOnly ◦ Chang tracking policy to DEFERRED_EXPLICIT or NOTIFY ◦ Provide flush arguments (applies objects and arrays)
  24. Presentation title here Doctrine Internals. UnitOfWork Links: docs • http://www.doctrine-project.org/api/orm/2.0/class-Doctrine.ORM.UnitOfWork.html

    • http://doctrine-orm.readthedocs.io/projects/doctrine-orm/ Patterns • http://martinfowler.com/eaaCatalog/unitOfWork.html • http://martinfowler.com/eaaCatalog/identityMap.html Sergey Zhuravel presentation about Doctrine Events • http://www.slideshare.net/sergeyz/oro-meetups-doctrine-events?qid=7d9177e9-c41c-4642- bdba-e1fa3060bb17&v=&b=&from_search=1