最新下载
热门教程
- 1
- 2
- 3
- 4
- 5
- 6
- 7
- 8
- 9
- 10
NHibernate 3 Lambda 配置实体二级缓存教程
时间:2026-09-21 19:18:02 编辑:袖梨 来源:一聚教程网
NHibernate 3 采用 lambda-configuration 配置实体缓存时,应当同时完成两层设置:用 cfg.Cache(...) 选择二级缓存 provider,再用 cfg.EntityCache<TEntity>(...) 为具体实体设置并发策略和 region。只配 provider 不会让所有实体自动进入缓存;只配实体而没有可用 provider,也无法得到生产可用的二级缓存。
配置前先确认是否适合缓存
适合实体二级缓存的对象通常是读多写少、多个 Session 会重复读取、且能接受所选一致性策略的数据。频繁更新、强一致性要求高、或在 NHibernate 之外经常被直接修改的表,不应默认使用宽松缓存策略。
本文使用 Product 作为贯穿实体,它已经通过 .hbm.xml 映射并包含 Categories 集合。
先配置全局缓存 provider
using NHibernate.Cache;
using NHibernate.Cfg;
using NHibernate.Cfg.Loquacious;
var cfg = new Configuration().Configure();
cfg.Cache(c =>
{
c.Provider<HashtableCacheProvider>();
c.UseMinimalPuts = true;
c.DefaultExpiration = 300;
c.RegionsPrefix = "catalog";
});
HashtableCacheProvider 是便于本地演示的进程内 provider,并不能让多个应用节点共享同一份缓存。生产环境应选择与 NHibernate 3 兼容、且满足部署拓扑和失效要求的 provider。
用 EntityCache 配置实体
必须先加载映射,再调用 EntityCache<T>,因为该 API 要从 Configuration 中找到实体和集合映射:
cfg.AddAssembly(typeof(Product).Assembly);
cfg.EntityCache<Product>(entity =>
{
entity.Strategy = EntityCacheUsage.NonStrictReadWrite;
entity.RegionName = "products";
entity.Collection(
product => product.Categories,
collection =>
{
collection.Strategy = EntityCacheUsage.NonStrictReadWrite;
collection.RegionName = "product-categories";
});
});
ISessionFactory sessionFactory = cfg.BuildSessionFactory();

从实际处理来看,官方测试会读回实体映射中的并发策略和 region,说明 EntityCache<T> 修改的是映射级缓存设置。
三种常见策略怎么选
| 策略 | 适用数据 | 主要限制 |
|---|---|---|
ReadOnly |
创建后不再修改的字典数据 | 不能用于正常更新的实体 |
NonStrictReadWrite |
读多写少,允许短暂不一致 | 并发更新期间可能读到旧值 |
ReadWrite |
需要更严格的更新协调 | provider 必须真正支持所需并发语义,成本也更高 |
不要只根据名字猜策略。先确认数据是否会被应用外部修改,再阅读当前 provider 对该策略的兼容说明。
缓存实体与缓存集合不是一件事
对 Product 的实体缓存命中,不代表 Product.Categories 这个集合也已缓存。集合缓存保存的通常是关联标识信息,关联实体自身还要有相应实体缓存,才能避免随后逐个加载。
如果并不需要集合缓存,就只设置实体策略,不要为了对称而给所有集合都创建 region。
验证二级缓存是否命中
一级缓存属于单个 ISession,所以验证二级缓存时必须使用两个不同 Session:
Product first;
using (var session = sessionFactory.OpenSession())
{
first = session.Get<Product>(1);
}
Product second;
using (var session = sessionFactory.OpenSession())
{
second = session.Get<Product>(1);
}
从实际处理来看,开启 NHibernate 统计后,检查第二次读取是否增加二级缓存 hit,并同时查看 SQL 日志是否少了实体查询。仅在同一 Session 中连续 Get 两次,只能证明一级缓存有效。
没有命中时按什么顺序查
- 检查
cfg.Cache(...)是否在BuildSessionFactory()前执行,provider 是否可加载。 - 检查映射是否在
EntityCache<T>之前加载,T是否正是映射的实体类型。 - 用两个 Session 验证,避免把一级缓存误认为二级命中。
- 如果测试的是普通 HQL/LINQ 列表查询,确认自己是否还需要查询缓存;实体二级缓存不会自动缓存查询结果集。
- 多节点部署中检查 region 前缀、节点配置和失效通知,不要用单进程 provider 推断集群行为。
总结
NHibernate 3 实体二级缓存的正确顺序是:选择兼容 provider,加载映射,用 EntityCache<T> 为实体及必要集合设置策略与 region,构建 SessionFactory,最后用跨 Session 读取和统计命中验证。只有当数据更新特性与缓存策略匹配时,性能提升才不会以错误数据为代价。
相关文章
- 安防通行场景的人脸抓拍与识别实践 09-21
- Flutter BoxConstraints 无限高度报错怎么修复 09-21
- ASP.NET 缓存与 GZIP 页面性能优化教程 09-21
- 14天做出AI产品:从最小Demo到首位付费用户 09-21
- Agent 009:用 Hooks 解耦智能体循环 09-21
- NHibernate 3 lambda-configuration 属性配置方法 09-21