2010-10-13 44 views
8

Je développe une application web et je voudrais que la mise en cache persiste à travers les requêtes web. Je suis conscient que le cache de premier niveau est uniquement par session. J'ai la mise en cache de second niveau activée et cela fonctionne pour les requêtes. Cependant, le cache de second niveau ne semble pas fonctionner pour "obtenir" des entités ... donc la plupart du travail de la base de données que l'application fait n'est pas mis en cache à travers les requêtes Web.NHibernate cache des entités à travers des sessions en utilisant SysCache

Est-ce un comportement normal/souhaitable? J'examine une page particulière qui fait beaucoup d'allers-retours à la base de données, bien que chaque requête soit rapide, cela ne semble pas nécessaire si les entités peuvent être mises en cache.

Modifier

Bon alors je cache de second niveau activé, et le travail pour les requêtes. Je n'arrive juste pas à le faire fonctionner pour les entités. J'ai Cache.Is(c => c.ReadWrite()) (fluent nhibernate) sur mon entité principale que je suis en train de tester. Mais non, il frappe toujours la DB à chaque fois. Des idées?

Modifier

J'ai essayé d'utiliser des transactions comme ceci:

public override Accommodation Get(int id) 
{ 
    using (var tx = Session.BeginTransaction()) 
    { 
     var accomm = Session.Get<Accommodation>(id); 
     tx.Commit(); 
     return accomm; 
    } 
} 

Ma cartographie est telle (et vous pouvez voir que nous avons un schéma méchant):

public void Override(AutoMapping<Core.Entities.Itinerary.Accommodation.Accommodation> mapping) 
{ 
    mapping.HasManyToMany(x => x.Features).Table("AccommodationLinkFeatureType").ChildKeyColumn("FeatureTypeId").NotFound.Ignore(); 
    mapping.HasManyToMany(x => x.SimilarAccommodation).Table("AccommodationLinkSimilarAccommodation").ChildKeyColumn("SimilarAccommodationId").NotFound.Ignore(); 
    mapping.HasMany(x => x.TourItinerary).Table("AccommodationTourItinerary"); 
    mapping.HasOne(x => x.Images).ForeignKey("AccommodationId").Cascade.All().Not.LazyLoad(); 
    mapping.References(x => x.CollectionType).NotFound.Ignore().Not.LazyLoad(); 
    mapping.References(x => x.AccommodationUnitType).NotFound.Ignore().Not.LazyLoad(); 
    Cache.Is(c => c.ReadWrite()); 
} 

Cependant, cela ne semble toujours pas aller chercher dans le cache de second niveau.

Soit dit en passant, je vois beaucoup d'exemples en ligne en Cache.ReadWrite(), mais je ne peux voir une méthode Is sur l'aide du cache, donc je suis en train Cache.Is(c => c.ReadWrite()) - a l'interface fluide changé?

+1

La meilleure façon économiserions votre session NHibernate à l'intérieur d'une session web, mais je ne recommande pas ceci: P Vous devriez probablement fixer votre mise en cache de niveau 2 - avez-vous lu ce post: http: // blogs.hibernatingrhinos.com/nhibernate/archive/2008/11/09/first-and-second-level-caching-in-nhibernate.aspx? – rsenna

+0

+1 pour le lien, mais voir mon édition –

+0

code + mappage? – Paco

Répondre

4

Je n'ai pas testé cela, mais je crois comprendre que les transactions de validation sont la magie qui place les objets dans le cache de second niveau. Si vous effectuez des opérations de lecture en dehors d'une transaction, les objets ne seront pas placés dans le cache de second niveau.

+0

Merci, je venais de le découvrir aussi. Voir http://nhprof.com/Learn/Alerts/DoNotUseImplicitTransactions –

+0

En fait, cela ne semble pas résoudre le problème. Voir éditer. –

0

J'ai eu le même problème. Dans mon cas, la cause était que les références sont mappées avec NotFound(). Ignore() (si aucune entité n'est trouvée avec cette clé étrangère, ignorez-la, ce qui est une erreur de cohérence des données). Supprimez NotFound.Ignore et corrigez votre db.

+0

Tant que c'est bien, sauf si vous travaillez avec une base de données existante sur laquelle vous n'avez pas un contrôle complet des données. –

0

Vous avez peut-être des problèmes avec la configuration de votre fournisseur de cache. Ive été en mesure de faire voulez que vous souhaitez en utilisant Couchbase comme 2ème niveau de fournisseur cache, comme décrit ici:

http://blog.couchbase.com/introducing-nhibernate-couchbase-2nd-level-cache-provider

Si votre déploiement est ambience sur Azure, je suppose que cela pourrait être utiles. Notez que le module SysCache ne peut pas coexister avec le module AzureMemcached.

http://www.webmoco.com/webmoco-development-blog/orchard-cms-second-level-caching