2012-05-15 13 views
5

Mam problem z doktryną. Lubię buforowanie, ale jeśli zaktualizuję Entity i Flush, czy doktryna2 nie powinna być w stanie wyczyścić pamięci podręcznej? W przeciwnym razie pamięć podręczna jest dla mnie bardzo mało użyteczna, ponieważ ten projekt ma dużo interakcji i musiałbym dosłownie zawsze wyłączyć pamięć podręczną dla każdego zapytania. Użytkownicy nie zobaczą ich interakcji, jeśli pamięć podręczna zawsze pokazuje im starą wersję z pamięci podręcznej.Doctrine2 Buforowanie zaktualizowanych elementów

Czy istnieje sposób arround niej?

+0

Czy chcesz całkowicie wyłączyć pamięć podręczną? Wiem, że możesz wyczyścić pamięć podręczną za pomocą $ deleted = $ cacheDriver-> deleteAll(); – Gohn67

+0

@ Gohn67: Jak mogę uzyskać CacheDriver? –

Odpowiedz

1

To jest według dokumentacji na Doctrine2 na temat sposobu, aby wyczyścić pamięć podręczną. Nie jestem nawet pewien, czy tego właśnie chcesz, ale myślę, że to jest coś, co trzeba spróbować.

kierowca cache Doctrine2 zawiera różne poziomy usuwania pamięci podręcznej wpisy.

można usunąć poprzez bezpośrednie id, używając regex, przez przyrostek poprzez prefiks i równiny usuwając wszystkie wartości w pamięci podręcznej

Tak, aby usunąć wszystkie chcesz zrobić:

$deleted = $cacheDriver->deleteAll(); 

I usunąć przez prefiks, można zrobić:

$deleted = $cacheDriver->deleteByPrefix('users_'); 

nie jestem pewien, jak Doctrine2 nazwy identyfikatorów cache choć, więc trzeba by wykopać za to.

Informacja dotycząca usuwania pamięci podręcznej można znaleźć tutaj: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html#deleting

Aby uzyskać sterownik pamięci podręcznej, można wykonać następujące czynności. Nie zostało to opisane w dokumentach, więc trochę prześledziłem kod.

Ja zakładając masz instancji menedżera podmiot w tym przykładzie:

$config = $em->getConfiguration(); //Get an instance of the configuration 
$queryCacheDriver = $config->getQueryCacheImpl(); //Gets Query Cache Driver 
$metadataCacheDriver = $config->getMetadataCacheImpl(); //You probably don't need this one unless the schema changed 

Alternatywnie Chyba można zapisać wystąpienie cacheDriver w jakiejś klasie rejestru i pobrać go w ten sposób. Ale zależy od twoich preferencji. Osobiście staram się nie polegać zbytnio na rejestrach.

Inną rzeczą, jaką możesz zrobić, to powiedzieć zapytanie jesteś wykonującemu nie używać pamięci podręcznej wynik. Znowu nie sądzę, że to jest to, czego chcesz, ale po prostu je wyrzucasz. Głównie wydaje się, że równie dobrze możesz całkowicie wyłączyć pamięć podręczną zapytań. Jest tak, chyba że jest to tylko kilka konkretnych zapytań, w których nie chcesz używać pamięci podręcznej.

Ten przykład jest z docs: http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html#result-cache

$query = $em->createQuery('select u from \Entities\User u'); 
$query->useResultCache(false); //Don't use query cache on this query 
$results = $query->getResult(); 
+1

Zastanawiam się, czy usunęli "deleteByPrefix()" na v.2.2.2? Przeszukałem pełne źródło doktryny i nie można znaleźć tej metody. –

+0

'deleteByPrefix' nie jest dostępny dla sterownika memcache. – Sithu

3

mówisz zapisywania i pobierania nowego podmiotu w tym samym czasie wykonywania (request)? Jeśli tak, to musisz odświeżyć encję.

$entity = new Entity(); 
$em->persist($entity); 
$em->flush(); 
$em->refresh($entity); 

Jeśli jednostka jest zarządzana i dokonać zmian, które zostaną zastosowane do obiektu Entity ale tylko utrzymywały się do bazy danych podczas wywoływania $ em-> flush().

Jeśli cache wraca stary zestaw danych dla nowego żądania (mimo to z powodzeniem zaktualizowany w DB), to brzmi jakbyś odkrył błąd. Który można złożyć tutaj >>http://www.doctrine-project.org/jira/secure/Dashboard.jspa

+0

Próbowałem dokładnie to. Ładuję encję, wprowadzam zmiany, utrzymuję ją, przepłukuję, odświeżam. Wciąż ten sam. Ale może to dlatego, że odświeżam encję i nie wszystkie jej powiązane obiekty, więc powiązane obiekty nadal pochodzą z pamięci podręcznej? –

+0

kiedy mówisz "ładuj" encję, masz na myśli tworzenie lub pobieranie jej z DB? Jeśli jest pobierany, to jest w stanie "zarządzanym" i nie musisz używać metody persist() na nim. Również odświeżenie zarządzanego elementu może usunąć wszelkie modyfikacje, które do niego wprowadziłeś. Jeśli jest nowy: create -> persist -> flush -> refresh. Jeśli jest zarządzany (pobrany z DB): pobierz -> (wprowadź zmiany) -> spłucz. –

+0

Próbowałem tego samego, odświeżanie naprawdę nie pomaga w "walce" z pamięcią podręczną. Działa to tak: $ entity = $ service-> loadCached(); echo $ entity-> getData(); // zwraca dane, które są buforowane $ em-> refresh(); echo $ entity-> getData(); // zwraca dane, które NIE są buforowane Które brzmi dobrze, ale w nie unieważnia rzeczywistej pamięci podręcznej, więc przy następnym uruchomieniu loadCached() nadal będziesz otrzymywał stare dane. Wygląda na to, że nie ma innego sposobu niż ręczne czyszczenie pamięci podręcznej, tak jak zasugerował Gohn67. –

3

Doctrine2 nie ma tych delegować metod, takich jak deleteByPrefix, który był w Doctrine1 w pewnym momencie (3 lata temu) i został usunięty, ponieważ spowodował więcej kłopotów.

Strona http://docs.doctrine-project.org/projects/doctrine-orm/en/latest/reference/caching.html#deleting jest nieaktualna (następna wersja dokumentu doctrine2 spowoduje usunięcie tych metod). Jedyne, co możesz teraz zrobić, to ręczne zarządzanie pamięcią podręczną: znajdź identyfikator i usuń go ręcznie po każdej aktualizacji.

Bardziej zaawansowane buforowanie doktryn to WIP: https://github.com/doctrine/doctrine2/pull/580.

+0

Tak, stary bilet, wciąż jestem ciekawy. Zajmuję się "deleteByPrefix", ale nie mogę znaleźć nic na ten temat. Jakie to miało problemy? Problemy z wydajnością? Może powinienem otworzyć właśnie nowe pytanie. – DoppyNL