簡體   English   中英

Doctrine2二級緩存僅使用ID而沒有關聯

[英]Doctrine2 Second level cache only working with ID and no associations

所以,我們有兩個實體

ProductBrand

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

我們已經使用Redis配置了Doctrine2 2lc

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

我們想要做的是緩存每個Brand和它的相關Product ,所以如果我們在緩存中檢索一個Brand ,它也會給我們它的Product

根據Doctrine的文檔,我們最終得到了上面的配置和這個查詢。

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

這實際上把我們所有的品牌都放到Redis中,如果我們再次進行查詢,不是在MySQL中觸發而是在Redis中觸發,這是可以的。

但在某些情況下我們不了解發生了什么

  1. 使用->find($id)命中緩存並從Redis中檢索我們的Brand ,但使用->findOneBy(array('name' => 'foo')); 不是從Redis獲取,它進行MySQL查詢,然后將查詢和結果緩存到Redis中,然后,第二次執行該查詢時,您將從Redis獲得foo品牌。 如果2lc正在緩存整個實體,為什么不嘗試查找name字段? 這實際上是在Redis中!

  2. 使用$result->getProducts()進行MySQL查詢,並緩存生成的實體,是不是已經存在於Redis中,因為我們已經配置了這種方式? (將YAML注釋中的緩存放入關聯映射中)

您正在使用Redis,但它可能是另一個緩存引擎(或在文件中)。 什么是緩存是結果的序列化作為鍵/值。 它不是使用Redis NoSQL系統來查詢redis中的結構化對象,如果它正是您要查找的內容。

緩存中的內容是盡可能原子序列化結果的關鍵值。 因此,在sql查詢中,您擁有所有主鍵,然后查詢的所有對象都將在緩存中單獨獲取。 因此,如果您更新其中一個品牌,則不需要使與其相關的所有緩存無效,而只需將包含該品牌的條目自身無效。

對於你的Brand-> products它是一回事,產品緩存條目是一個只包含產品id的集合,第一次調用getProducts會觸發查詢,第二次不會。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM