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

Demystifying cache in Doctrine ORM

Luís Cobucci
September 21, 2017

Demystifying cache in Doctrine ORM

Applications should be fast regardless of any cache system. However, sometimes we do need to cache data in order to optimise things and deliver a fast response to the clients.
This talk covers the different types of cache offered Doctrine ORM (metadata, query, result set, and second level cache), how they work together with the Unit of Work and what we should know before caching all the things.

Luís Cobucci

September 21, 2017
Tweet

More Decks by Luís Cobucci

Other Decks in Technology

Transcript

  1. “ There are two hard things in Computer Science: cache

    invalidation, naming things, and off-by-one errors Common sense
  2. “ a hardware or software component that stores data so

    future requests for that data can be served faster; the data stored in a cache might be the result of an earlier computation, or the duplicate of data stored elsewhere. Cache (computing) - Wikipedia
  3. Our software Cache External API 2. Cache miss 3. Give

    me data 1. Give me “external.result”
  4. Our software Cache External API 2. Cache miss 3. Give

    me data 4. There you go 1. Give me “external.result”
  5. Our software Cache External API 2. Cache miss 1. Give

    me “external.result” 3. Give me data 4. There you go 5. Store “external.result”
  6. Our software Cache External API 2. Cache miss 1. Give

    me “external.result” 3. Give me data 4. There you go 5. Store “external.result” 6. Stored!
  7. Template Message Consumer Campaign 1 1 1 * * *

    INSERT INTO consumer (name, email)
 VALUES (“Luís Cobucci”, “[email protected]”);
 SET @consumer_id = LAST_INSERT_ID();
  8. Template Message Consumer Campaign 1 1 1 * * *

    INSERT INTO consumer (name, email)
 VALUES (“Luís Cobucci”, “[email protected]”);
 SET @consumer_id = LAST_INSERT_ID(); INSERT INTO template (name, body)
 VALUES (“Template 1”, “blah… blah… blah…”);
  9. Template Message Consumer Campaign 1 1 1 * * *

    INSERT INTO consumer (name, email)
 VALUES (“Luís Cobucci”, “[email protected]”);
 SET @consumer_id = LAST_INSERT_ID(); INSERT INTO template (name, body)
 VALUES (“Template 1”, “blah… blah… blah…”); INSERT INTO campaign (title, template_id, message)
 VALUES (“Test”, LAST_INSERT_ID(), “blah… blah… blah…”);
  10. Template Message Consumer Campaign 1 1 1 * * *

    INSERT INTO consumer (name, email)
 VALUES (“Luís Cobucci”, “[email protected]”);
 SET @consumer_id = LAST_INSERT_ID(); INSERT INTO template (name, body)
 VALUES (“Template 1”, “blah… blah… blah…”); INSERT INTO campaign (title, template_id, message)
 VALUES (“Test”, LAST_INSERT_ID(), “blah… blah… blah…”); INSERT INTO message (campaign_id, consumer_id, sent)
 VALUES (LAST_INSERT_ID(), @consumer_id, FALSE);
  11. Template Message Consumer Campaign 1 1 1 * * *

    INSERT INTO consumer (name, email)
 VALUES (“Luís Cobucci”, “[email protected]”);
 SET @consumer_id = LAST_INSERT_ID(); INSERT INTO template (name, body)
 VALUES (“Template 1”, “blah… blah… blah…”); INSERT INTO campaign (title, template_id, message)
 VALUES (“Test”, LAST_INSERT_ID(), “blah… blah… blah…”); INSERT INTO message (campaign_id, consumer_id, sent)
 VALUES (LAST_INSERT_ID(), @consumer_id, FALSE); Don’t forget to use a transaction!
  12. declare(strict_types=1); $consumer = new Consumer('Luís Cobucci', '[email protected]');
 $template = new

    Template('Template 1', 'blah… blah… blah…');
 $campaign = new Campaign($template, 'Test', 'blah… blah… blah…');
 $message = new Message($campaign, $consumer, false);
 
 $entityManager->persist($consumer); $entityManager->persist($template); $entityManager->persist($campaign); $entityManager->persist($message); $entityManager->flush();
  13. declare(strict_types=1); $consumer = $entityManager->find('Consumer', 2); $campaign = $entityManager->find('Campaign', 1);
 


    $message = new Message($campaign, $consumer, false);
 
 $entityManager->persist($message); $entityManager->flush();
  14. /** @ORM\Entity */ class Consumer
 {
 /** 
 * @ORM\Id


    * @ORM\GeneratedValue 
 * @ORM\Column(type="integer")
 */ private $id;
 
 /** @ORM\Column(type="string") */
 private $name;
 
 /** @ORM\Column(type="string") */
 private $email; }
  15. /** @ORM\Entity */ class Consumer
 {
 /** 
 * @ORM\Id


    * @ORM\GeneratedValue 
 * @ORM\Column(type="integer")
 */ private $id;
 
 /** @ORM\Column(type="string") */
 private $name;
 
 /** @ORM\Column(type="string") */
 private $email; } ClassMetadata
  16. SELECT consumer FROM Consumer consumer; SELECT
 c0.id AS id_0,
 c0.name

    AS name_1, c0.email AS email_2,
 FROM consumer c0;
  17. $query = 'SELECT COUNT(m) FROM Message m WHERE m.user =

    :user'; 
 $count = $entityManager->createQuery($query)
 ->setParameter('user', 1)
 ->getSingleScalarResult();
  18. $query = 'SELECT COUNT(m) FROM Message m WHERE m.user =

    :user'; 
 $count = $entityManager->createQuery($query)
 ->setParameter('user', 1)
 ->useResultCache(true)
 ->useResultCacheLifeTime(3600)
 ->getSingleScalarResult();
  19. /**
 * @ORM\Entity
 * @ORM\Cache(usage="NONSTRICT_READ_WRITE")
 */ class Message
 {
 //

    …
 
 /**
 * @ORM\ManyToOne(targetEntity="Consumer") * @ORM\Cache(usage="READ_ONLY") */
 private $consumer; 
 // …
 }
  20. $query = ‘SELECT m FROM Message m WHERE m.user =

    :user'; 
 $messages = $entityManager->createQuery($query)
 ->setParameter('user', 1)
 ->setCacheable(true)
 ->getResult();