2011-09-07 11 views
3

Nous utilisons intensivement la fonctionnalité multi-requêtes de NHibernate et expérimentons un comportement étrange. On dirait que NHibernate ne met pas en cache les multiqueries et qu'il frappe toujours la base de données. Nous utilisons QueryOver, toutes les requêtes sont configurables, mais lors du test de la page d'accueil avec blitz.io avec le modèle -p 1-250:30, je peux voir que la seule requête multiple qui frappe la base de données est exécutée plus de 2000 fois, alors que d'autres requêtes utilisateur connecté) ne sont exécutés qu'une ou deux fois. Donc, la question est: ai-je oublié quelque chose ou NHibernate ne cache pas vraiment les résultats de plusieurs requêtes?Mise en cache NHibernate de second niveau avec multi-requête

Répondre

4

Aha, j'ai compris! Comme il s'est avéré, ce n'était pas la faute du cache de second niveau, mais plutôt notre utilisation de QueryOver est à blâmer.

Comme nous écrivons une application SaaS multi-locataires, la plupart de nos requêtes ressemblait à ceci:

return 
    Session.QueryOver<Article>().Cacheable(). 
     Where(a => a.Site == site && a.PublishedAt <= publishedAt). 
     OrderByCoalesceDesc(typeof(DateTime), a => a.UpdatedAt, a => a.CreatedAt). 
     Take(count). 
     Future(); 

Et a.Site == site était le problème. Apparemment, la façon dont le cache de requête vérifie si les résultats de la requête sont mis en cache ou non est essentiellement en utilisant une combinaison d'une instruction SQL et de tous les paramètres comme clé du cache "hashtable". Le texte de l'instruction SQL est toujours le même pour nos multi-requêtes, mais le paramètre site était le coupable. NH vérifie pour voir si tous les paramètres fournis correspondent à ceux déjà dans le cache et naturellement nous n'avons pas Equals() implémenté dans notre classe Site, donc la vérification a toujours échoué.

Ce que nous avons fini avec réécrivait nos requêtes comme ceci:

var siteID = site.ID; 
return 
    Session.QueryOver<Article>().Cacheable(). 
     Where(a => a.Site.ID == siteID && a.PublishedAt <= publishedAt)... 
Questions connexes