在Asp.net中使用NHibernate的问题
在前面使用NHibernate的经验中,因为做的是客户端,所以把所有的变量都做成静态变量,比如Session和SessionFactory,而且理论上来说Session可以一直开着,直接程序关闭的时候再关闭。但是在开发Asp.net的时候肯定是不可以一直开着的,不过前期开发的时候还是使用静态变量的方式保存Session。结果程序写的差不多了的时候使用VS2003自带的Application Test Center测试网站的运行效率,当只模拟一个客户端的时候程序运行良好,而且速度很快,设成两个客户端以后,突然全部变成HTTP错误,关闭测试,再打开网站也不行了,提示当前的Command是关闭的之类的。
原来NHibernate的Session不是线程安全的,而且使用静态变量的方法来传递变量会导致整个IIS环境内都使用这同一个变量,因为当两个客户端同时操作的时候,就会冲突报错,不过SessionFactory是线程安全的。因此,只能将SessionFactory使用静态变量来传递,在需要使用Session时创建。不过创建Session的过程是很慢的,而且对于同一个HTTP请求来说,创建多个线程完全是多余行为,也是浪费。
因此,正规的解决方案是,建一个SessionFactory变量保存在Application级上下文中,供所有操作共享,然后为每个请求建一个Session变量,保存在HttpContext的上下文中,供该请求共享,在进入的时候打开Session,请求结束的时候关闭Session。这样的话就要求自己建一个HttpModule挂到系统上并绑定BeginRequest和EndRequest事件。
但是这样的话就没有办法使用单元测试了,一个解决方法是在这个HttpModule中增加一个静态变量用来保存Session,在创建和获取Session的函数中判断当前的HttpContext是否为空,如果是,说明没有以Web方式运行,则以静态变量的方式来使用。试用之下,效果良好。
推荐到鲜果:


评论