Asp.Net中NHiernate的Session的管理

NHibernate中的Session,在我的理解似乎就相当于数据库中连接。因为它也有Open/Close的方法,我没有研究NHibernate的源码,不知道这种理解是否有误?我在网上搜了很多的关于Session的管理,大多都是在我需要数据库操作的时候,就OpenSession(),操作完后就CloseSession().这有点拟似如我们刚开始学习ADO.NET的时候,要Connection对象Open(),数据处理完后就Close().但是这里就带来了一个弊端,因为Connection的频繁的开关是非常消耗系统资源的。我记得以前在制作一个数据的录入界面的时,因为这个录入的界面数据元素比较多,而且很多DropDownList需要在数据库中读取数据并绑定。
这样在该页面的Page_Load中需要调用相应对象的方法一一从数据库中检索数据绑定DropDownList.因为我们这些对象的方法都是使用独立的Connection,都有自己的Connection的Open和Close。所以,导致这个页面一打开就需要等待好长的时间,比较慢。后来我们将这些需要绑定DropDownList的数据通过一个数据处理成一个DataSet,并将DataSet中的DataTable与DropDownList绑定。这样只需要一次的Connection的Open/Close.页面快了好多。
 
所以,我觉得上述的Session的管理办法不是很妥当。
 
后来,我看了Cuyahoga开源项目中他的Session管理,他使用的“session-per-request”这种模式。
从字面上理解就是他为每个Request创建一个Session,直到这个请求销毁,那么这个Session也就Close了。
而Cuyahoga他的做法和session-per-request有点不同地方就是,他为每个Request都创建了一个CoreRepository对象,CoreRepository是系统所需要的数据处理服务的类。
他的做法是先创建了HttpModule(NHSessionModule)用来创建CoreRepository对象和销毁CoreRepository对象,如下:
private void Context_BeginRequest(object sender, EventArgs e)
  
{
   
// Create the repository for Core objects and add it to the current HttpContext.
   CoreRepository cr = new CoreRepository(true);
   HttpContext.Current.Items.Add(
"CoreRepository", cr);
  }

 
  
private void Context_EndRequest(object sender, EventArgs e)
  
{
   
// Close the NHibernate session.
   if (HttpContext.Current.Items["CoreRepository"!= null)
   
{
    CoreRepository cr 
= (CoreRepository)HttpContext.Current.Items["CoreRepository"];
    cr.CloseSession();
   }

  }

 
这样在每次请求的时候,会自动创建CoreRepository对象,当请求完毕后,就CloseSession(),在程序中通过HttpContext.Current.Items["CoreRepository"]就能获取CoreRepository对象了。
 
这样也就变相的管理了NHibernate中的Session,也就达到了“session-per-request”的这种模式。
 
 
这种方式比上面的那个每次操作都需要创建Session,性能和速度应该提高了不少,
接着我就想,每个请求都创建Session,是不是我们可以象创建Connection Pool一样,也创建一个Session Pool,
这样就每次请求的时候不是直接创建Session,而是在我们的Session Pool中拿已经创建好的Session,这样效率不是更好?!
posted @ 2006-06-26 11:08 福娃 阅读(1811) 评论(17)  编辑 收藏 网摘

  回复  引用  查看    
#1楼  2006-06-26 11:45 | henry      
在.Net平台下自己建一个Connection Pool是否真的会比New一个Connection 效率要高?
如果楼主有这样一个Connection Pool能否共享一下.

  回复  引用  查看    
#2楼  2006-06-26 11:47 | main      
最近一直关注这个方面的东西。继续关注中。。。
  回复  引用  查看    
#3楼  2006-06-26 11:50 | main      
@henry
ado.net自管理connection pool ,难道意味没有更优秀的连接池了吗?
难说哦。当然如果有最好

  回复  引用  查看    
#4楼  2006-06-26 11:52 | cnlamar      
pool似乎没什么必要了

我对nh的session管理一直是采用的,需要的时候打开,页面结束的时候关闭,自己做了一个管理器,不过没用到httpmodule方式,想想,其实可以用module方式实现出来更简洁,呵呵。。。

  回复  引用  查看    
#5楼  2006-06-26 11:56 | cnlamar      
实现起来也很简单,做一个计数器,打开的时候+1,关闭的时候-1,-1结果为0的时候真正关闭,执行任何数据操作的时候,真正打开会话,然后在页面最开始的时候调用管理器里的OPEN操作,给计数器+1,但实际上会一直到真正有数据操作的时候,才实际打开会话,并且操作前再OPEN一次,操作完CLOES一次,最后在页面结束的时候,再CLOSE一次,并把管理器对象放入httpcontext中去,建立对象的时候,首先会检查是否存在,存在则取出,不存在则创建并放入。
  回复  引用  查看    
#6楼  2006-06-26 12:02 | henry      
@main
晕,我那说没有更好的!
只是我能力有限找不到也实现不了才问下楼主有没这方面的东西.
pool的意图是用来解决效率,但关键还是要看实现。

  回复  引用  查看    
#7楼  2006-06-26 12:08 | kiler      
java那边好像都是这么做的,而且他们那边在请求开始的时候打开一个事务,在请求结束的提交这个事务,每一个request就是一个事务,编程的时候就不考虑事务了。
  回复  引用  查看    
#8楼  2006-06-26 12:08 | main      
@henry
hehe,你是我的偶像,一直关注你的blog,小弟理解错了。呵呵

  回复  引用  查看    
#9楼 [楼主] 2006-06-26 12:08 | 福娃      
写这篇文章的时候,突然想到的,还不知道是否可行性,
如果大家觉得可行,晚上我来写一个,以前写过Connection的Pool,应该道理是一样的。


  回复  引用  查看    
#10楼  2006-06-26 13:18 | 自適應軟件......      
為甚麼Open以後Close?我想主要是從安全性和系統開銷的角度區考慮的!用Connection Pool對於App可能會快點,可是也會增加DBServer的開銷吧?
  回复  引用  查看    
#11楼  2006-06-26 13:40 | wonder      
楼主。。。。
你理解错了吧。。。。

Connection.open();------从池中打开一个连接。。。。。
Connection.close(),------把打开的连接返回连接池。。。。

注意:连接数是有限的。。。。。


所以你打开一个连接之后。。。必须在不使用的时候close掉。。。。。

  回复  引用  查看    
#12楼  2006-06-26 14:11 | 蛙蛙池塘      
就是,本来就有池的。
  回复  引用    
#13楼  2006-06-26 14:23 | yifeng [未注册用户]
如上说,效率都不是很担心。

我认为open-per-request主要解决object的lazy load问题。

  回复  引用    
#14楼  2006-06-26 15:37 | zergtant [未注册用户]
这里有个源代码楼主研究下http://www.codeproject.com/aspnet/NHibernateBestPractices.asp
我很久不用nhibernate了,我当时用nhibernate就是参考的这份代码不知道是不是你所说的,但是这份源代码很好,用到了泛型等2.0的新特性,修改非常方便

  回复  引用  查看    
#15楼 [楼主] 2006-06-26 17:36 | 福娃      
@zergtant
谢谢提供,下载中...

  回复  引用  查看    
#16楼  2006-06-26 19:46 | Na57      
我觉得NHibernate打开和关闭Session并不会消耗多少时间.
我在做单元测试的时候计算过时间,第一次打开Session的时候确实会消耗大量的时间,因为NHiberante需要读取配置文件,打开数据库连接等.但是,第二次打开Session就快很多了.一般执行一次数据库操作都在0.02秒以内,而且,以后都会保持这个速度.

  回复  引用  查看    
#17楼  2006-06-26 21:27 | 蔡克伦      
做个小广告,我这儿有个nhibernate + asp.net2.0 + XMLHTTP实际项目的例子,完全开源:
http://nomagic.cnblogs.com/archive/2006/05/28/411547.aspx


发表评论



姓名 [登录] [注册] 
主页
Email (仅博主可见) 
验证码 *  验证码看不清,换一张
内容(请不要发表任何与政治相关的内容)  
  登录  使用高级评论   新用户注册   返回页首      

导航: 网站首页 社区 新闻 博问 闪存 网摘 招聘 .NET频道 知识库 找找看 Google站内搜索



China-pub 计算机图书网上专卖店!6.5万品种 2-8折!
China-Pub 计算机绝版图书按需印刷服务

相关文章:

相关链接: