简体   繁体   中英

NHibernate and potential caching problems

Ok so I have an n tiered model. (WPF, Asp.Net, etc) to backend services via WCF. These services use NHibernate to communicate with the database. Some of these services will be run in InstanceContextMode.Single mode.

Questions:

  1. In singleton service instances should I try to utilize 1 session object for the entire time the wcf service is alive to get the most out of my cache?
  2. If I use 1 session instance in this singleton instance and never create new ones I assume I have to worry about eventually removing cached entities from the session or dumping it all together to avoid performance issues with the session?
  3. Is it a good idea at all to use the session in this way for a singleton wcf service? It seems like it would be if I want to utilize caching.
  4. Should I utilize 2nd level cache in a scenario like this?
  5. Outside of this scenario when should I avoid caching? I would assume that I would want to avoid it in any sort of batching scenario where a large number of objects are created/updated and never really used again outside of the creation or updates.
  6. Are items automatically cached in session when I create/read/update/delete or do I need to specify something in the mapping files or configuration?

1-3: As far as I know, ISession objects are supposed to be light-weight, short-lived objects, which live only for the duration for which they're needed. I would advise AGAINST using the same ISession object for the whole lifetime of your service.
What I would suggest instead is using the same ISeessionFactory instance, and creating new ISessions from it as necessary (you can try something similar to Session-Per-Request pattern).
If you enable 2nd level cache, you can have all the benefits of caching in this scenario.

5 Yep, pretty much. Also remember that 2nd level cache instance is per ISessionFactory instance . that means that if you're using more than 1 ISessionFactory instance you'll have a lot of problems with your cache.

6 for 1st level cache you don't need to define anything.
for 2nd level cache you need to enable the cache when you configure nHibernate (fluently, in my case):

.Cache(c => c.UseQueryCache()
                                    .ProviderClass(
                                    isWeb ? typeof(NHibernate.Caches.SysCache2.SysCacheProvider).AssemblyQualifiedName //in web environment- use sysCache2
                                        : typeof(NHibernate.Cache.HashtableCacheProvider).AssemblyQualifiedName //in dev environmet- use stupid cache
                                    )) 
                          )

and specify for each entity and each collection that you want to enable cache for them:

mapping.Cache.ReadWrite().Region("myRegion");

and for a collection:

mapping.HasMany(x => x.Something)
.Cache.ReadWrite().Region("myRegion");

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM