2016-05-13 8 views
1

So haben wir zwei EinheitenDoctrine2 Second-Level-Cache arbeiten nur mit ID und keine Assoziationen

Product und Brand.

AppBundle\Entity\Brand: 
    type: entity 
    id: 
     id: 
      type: integer 
      generator: 
       strategy: AUTO 
    cache: 
     usage : READ_ONLY 
     region : region_products 
    oneToMany: 
     products: 
      targetEntity: AppBundle\Entity\Product 
      mappedBy: brand 
      cache: 
       usage : READ_ONLY 
      cascade: ["remove", "persist"] 
      orderBy: { 'name': 'ASC' } 


AppBundle\Entity\Product: 
    type: entity 
    cache: 
     usage : READ_ONLY 
     region : region_products 
    id: 
     id: 
      type: integer 
      generator: 
       strategy: AUTO 

    manyToOne: 
     brand: 
      targetEntity: AppBundle\Entity\Brand 
      inversedBy: products 
      joinColumns: 
       brand_id: 
        referencedColumnName: id 
      cache: 
       usage : READ_ONLY 

Wir konfiguriert haben Doctrine2 2LC mit Redis

services: 
    snc_second_level_cache: 
     class: "%snc_redis.doctrine_cache_phpredis.class%" 
     calls: 
      - ["setRedis", ["@snc_redis.second_level_cache"]] 
      - ["setNamespace", ["slc_"]] 

doctrine: 
    orm: 
     result_cache_driver: redis 
     metadata_cache_driver: redis 
     query_cache_driver: redis 
     second_level_cache: 
      region_cache_driver: 
       type: service 
       id: snc_second_level_cache 
      region_lock_lifetime: 60 
      log_enabled: true 
      region_lifetime: 300 
      enabled: true 
      regions: 
       region_products: 
        cache_driver: 
         type: service 
         id: snc_second_level_cache 
        lifetime: 300 

Und was wollen wir jeden Brand tun, ist das Caching und es Product bezogen, so dass, wenn wir einen Brand im Cache abrufen, es gibt uns, es ist Product auch.

Nach Doctrine-Dokumentation, endete mit der obigen Konfiguration und dieser Abfrage.

$em = $this->get('doctrine.orm.entity_manager'); 
$result = $em->getRepository('AppBundle:Brand')->findAll(); 

Damit sind eigentlich alle unsere Marken in Redis, wenn wir die Abfrage erneut tun, wird stattdessen nicht ausgelöst in MySQL aber Redis, was in Ordnung ist.

Aber es gibt einige Fälle, in denen wir nicht verstehen, was auf

  1. Mit ->find($id) trifft den Cache wird und unsere Brand von Redis abzurufen, aber ->findOneBy(array('name' => 'foo')); mit nicht von Redis holen, es macht eine MySQL-Abfrage und dann beide, Abfrage und Ergebnis in Redis, dann, das zweite Mal, dass Sie diese Abfrage durchführen, erhalten Sie foo Marke von Redis. Wenn 2LC die gesamte Entität zwischenspeichert, warum versucht es nicht, in name Feld zu finden? Welches ist eigentlich in Redis !.

  2. Mit $result->getProducts() macht eine MySQL Abfrage und speichert die resultierenden Einheiten ist es nicht supossed in Redis bereits sein, da wir auf diese Weise konfiguriert haben? (Mit Cache im YAML Anmerkung in die Assoziationskartierung)

Antwort

0

Sie verwenden Redis, aber es könnte eine andere Cache-Maschine (oder seine in der Datei) sein. Was ist Cache ist eine Serialisierung des Ergebnisses als Schlüssel/Wert. Es verwendet das Redis NoSQL-System nicht, um ein strukturiertes Objekt in redis abfragen zu können, wenn es das ist, wonach Sie suchen.

Was Sie im Cache haben, ist ein Schlüsselwert der Serialisierung des Ergebnisses so atomar wie möglich. Also in einer SQL-Abfrage haben Sie alle Primärschlüssel und dann alle Objekte der Abfrage einzeln im Cache abrufen. Also, wenn Sie eine Ihrer Marke aktualisieren, muss es nicht den gesamten damit verbundenen Cache ungültig machen, sondern nur den Eintrag, der die Marke selbst enthält.

Für Sie Brand-> Produkte ist es die gleiche Sache, die Produkte Cache-Eintrag ist eine Sammlung, die nur die ID für das Produkt enthalten, das erste Mal rufen Sie die GetProducts wird eine Abfrage auslösen, das zweite Mal wird es nicht.

Verwandte Themen