NHibernate使用无状态Sessions
NHibernate 3.0 Cookbook第三章,Using stateless sessions的翻译.
当要处理大量的数据,你通常可能会使用更"底层"的API来改善性能,在这次处理中很多时候会关闭一些高级特性.在NHibernate中,无状态Session就是高性能,底层的API.
这个文章,我们会使用一个无状态的Session来更新我们的电影价格.
准备
像前面的一样,建立一个控制台应用程序,参考第二章使用app.config配置NHibernate,使用Eg.Core Model.
怎样做
1.创建一些数据,添加下面代码到你的Main方法中:
using (var session = sessionFactory.OpenStatelessSession()) { using (var tx = session.BeginTransaction()) { for (int i = 0; i < 1000; i++) session.Insert(new Movie() { Name = "Movie " + i.ToString(), Description = "A great movie!", UnitPrice = 14.95M, Director = "Johnny Smith" }); tx.Commit(); } }
2.下一步,去更新我们的电影的价格,在Main方法中添加如下代码:
using (var session = sessionFactory.OpenStatelessSession()) { using (var tx = session.BeginTransaction()) { var movies = GetMovies(session); foreach (var movie in movies) { UpdateMoviePrice(movie); session.Update(movie); } tx.Commit(); } }
3.添加GetMovies方法:
static IEnumerable<Movie> GetMovies(IStatelessSession session) { return session.CreateQuery("from Movie") .List<Movie>(); }
4.最后,添加UpdateMoviePrice方法:
static Random rnd = new Random(); static void UpdateMoviePrice(Movie movie) { // Random price between $9.95 and $24.95 movie.UnitPrice = (decimal)rnd.Next(10, 26) - 0.05M; }
原理
使用一个无状态Session,我们新建了1000个电影.无状态的Session没有实现transactional write-behind,也就是说SQL语句不会延迟到我们提交事务才执行.然而,当我们打开批处理,它们不会立即执行.同一时间会有100条插入语句排队等候并且一起发送所有语句.如果我们关闭批处理,这样就会每调用session.Insert就会马上发送一条语句.
下一步,我们用一条查询语句获取所有电影.这些电影是游离态的;它们没有和一个Session关联.实体不会与无状态的Session关联.无论我们使用查询还是Get方法加载实体都是这样的情况.
因为无状态Session没有实现自动脏检查(automatic dirty checking),我们必须调用session.Update来保存电影的改变.
There's more...
一个无状态Session本质上是一个标准Session的简化版.它不使用一级缓存,也不执行自动脏检查(automatic dirty checking),也不支持延迟加载.实际上,它甚至没有保存实体的引用,以帮助防止处理数千实体时内存泄漏.级联被忽略.你每次都必须明确地插入,更新,或者删除每个实体.无状态Session还会忽略二级缓存,事件监听(event listeners),拦截器(interceptors),甚至NHibernate.SQL的log4net记录器.
尽管有这些局限性,当你需要使用真实对象(real objects)时,无状态Session在高性能批处理情景中是非常有用的.当你要用原始数据(raw data)时,这里通常有更好的代替方案,例如简单的旧的SQL(plain old SQL),HQL批处理(HQL bulk actions),SqlBulkCopy,或者ETL tools.至于简单的旧的SQL(plain old SQL),session.Connection属性使得可以简单地使用ADO.NET的connection对象,然后你可以像以前那样写ADO.NET代码.
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述