|
NHibernate中Session是线程不安全的,而且每次数据库操作 请求创建Session时对性能有些影响。在Windows应用中可以通过 [ThreadStatic]特性很简单的就可以实现线程安全,而在Web中可以通过将Session与用于请求HttpContext绑定实现线程安全,并且用户当前请求时只有一个Session。代码如下:
ISessionManage.cs
using System; using NHibernate;
namespace Commercial.Jwsoft.Framework.Persistence.SessionManage { /// <summary> /// 功能:主要用于封装第三方类库操作数据库的Session类,现主要用于封装NHibernate中的Session /// </summary> public interface ISessionManage { /// <summary> /// 获取Session的一个实例 /// </summary> /// <returns>返回实现NHibernate.ISession接口的类</returns> ISession Get();
/// <summary> /// 设置Session的一个实例 /// </summary> /// <param name="session">实现NHibernate.ISession接口的类</param> void Set(ISession session); } }
--------------------------------------------
WebNHSession.cs
using System; using System.Web; using NHibernate;
namespace Commercial.Jwsoft.Framework.Persistence.SessionManage { /// <summary> /// 功能:此类用于Web应用,NHibernate提供的Session有两个缺陷: /// 一方面是线程不安全的,另一方面每次数据库操作创建一个Session对程序性能有影响。 /// 因此通过将Session绑定到HttpContext上,这样每个用户具有唯一的一个Session,而且 /// 在用户的请求结束后关闭Session并自己释放掉。 /// </summary> public class WebNHSession : ISessionManage { public WebNHSession() {
}
/// <summary> /// 获取存储到HttpContext中的实现NHibernate.ISession接口的类实例 /// </summary> /// <returns>实现NHibernate.ISession接口的类实例,当用户之前没有调用Set方法会返回Null</returns> public ISession Get() { return (ISession)HttpContext.Current.Items[SessionConfigManage.SessionSourceItemName]; }
/// <summary> /// 存储实现NHibernate.ISession接口的类实例到HttpContext中 /// </summary> /// <param name="session">实现NHibernate.ISession接口的类实例</param> public void Set(ISession session) { if (session != null) { HttpContext.Current.Items.Add(SessionConfigManage.SessionSourceItemName, session); } else { HttpContext.Current.Items.Remove(SessionConfigManage.SessionSourceItemName); } } } } ---------------------------------------------
WinFormNHSession.cs
using System; using NHibernate;
namespace Commercial.Jwsoft.Framework.Persistence.SessionManage { /// <summary> /// 功能:此类用于Windows应用,NHibernate提供的Session有两个缺陷: /// 一方面是线程不安全的,另一方面每次数据库操作创建一个Session对程序性能有影响。 /// 因此通过线程变量获取一个NHibernate Session的多个线程安全的实例,而且线程变量使用后即释放掉。 /// </summary> public class WinFormNHSession : ISessionManage { [ThreadStatic] private static ISession _threadSession = null;
public WinFormNHSession() { }
/// <summary> /// 获取存储到线程变量中的实现NHibernate.ISession接口的类实例 /// </summary> /// <returns>实现NHibernate.ISession接口的线程安全的类实例,当用户之前没有调用Set方法会返回Null</returns> public ISession Get() { if (_threadSession != null) { if (_threadSession.IsConnected) { _threadSession.Reconnect(); } } return _threadSession; }
/// <summary> /// 存储实现NHibernate.ISession接口的类实例到线程变量中 /// </summary> /// <param name="session">实现NHibernate.ISession接口的类实例</param> public void Set(ISession session) { if (_threadSession.IsConnected) { session.Disconnect(); } _threadSession = session; } } }
----------------------------------------------
SessionFactory.cs
using System; using System.Runtime.Remoting; using NHibernate;
namespace Commercial.Jwsoft.Framework.Persistence.SessionManage { /// <summary> /// 功能:管理多个实现ISessionManage接口的类工厂,根据读取的要加载的类名称信息,进行动态的创建Session /// </summary> public class SessionFactory { private static ISession session = null; private static ISessionManage sessionManage = null; static SessionFactory() { Init(); }
/// <summary> /// 获取实现NHibernate.ISession接口的Session实例 /// </summary> /// <returns>返回实现NHibernate.ISession接口的类实例</returns> public static ISession GetSession() { session = sessionManage.Get(); if (session == null) { session = NHibernateSession.GetNHibernateSession(); sessionManage.Set(session); }
return session; }
private static void Init() { System.Reflection.Assembly ass = System.Reflection.Assembly.Load(SessionConfigManage.AssemblyName); sessionManage = (ISessionManage)ass.CreateInstance(SessionConfigManage.SessionSourceItemName); } } } ----------------------------------------------
NHibernateSession.cs
using System; using System.Data; using System.Collections.Generic; using System.Text; using NHibernate; using NHibernate.Cfg;
namespace Commercial.Jwsoft.Framework.Persistence.SessionManage { /// <summary> /// 功能:加载嵌入资源(Xml配置文件),打开一个SessionFactory,获取NHibernate的Session实例 /// </summary> public class NHibernateSession { private static Configuration cfg = null; private static ISessionFactory sessionFactory = null;
static NHibernateSession() { cfg = new Configuration().Configure(); sessionFactory = cfg.BuildSessionFactory(); }
/// <summary> /// 获取NHibernate的Session实例 /// </summary> /// <returns></returns> public static ISession GetNHibernateSession() { return sessionFactory.OpenSession(); } } } ---------------------------------------------
SessionConfigManage.cs
using System; using System.Collections.Generic; using System.Text; using System.Configuration;
namespace Commercial.Jwsoft.Framework.Persistence.SessionManage { /// <summary> /// 功能:根据类库的应用环境不同(Windows应用还是Web应用),动态创建类实例 /// 日期:2006-08-24 /// 作者:郭少宏 /// </summary> public class SessionConfigManage { private const string SESSION_ITEM_NAME = "SessionItemName"; private static object _locker = new object(); private static string _sessionItemName = string.Empty; private static string _assemblyName = string.Empty;
static SessionConfigManage() { string configString = ConfigurationManager.AppSettings[SESSION_ITEM_NAME]; string[] arr = configString.Split(’,’); _sessionItemName = arr[0]; _assemblyName = arr[1]; } /// <summary> /// 获取配置文件中名为SESSION_ITEM_NAME配置节的信息,记录的要加载的SessionManage的类全称 /// </summary> /// <returns>实现ISessionManage接口的类的名称</returns> public static string SessionSourceItemName { get { lock (_locker) { return _sessionItemName; } } }
/// <summary> /// 获取配置文件中名为SESSION_ITEM_NAME配置节的信息,记录的要加载的SessionManage的类全称 /// </summary> /// <returns>实现ISessionManage接口的类的程序集名称</returns> public static string AssemblyName { get { lock (_locker) { return _assemblyName; } } } } }
在Web.Config文件中的配置节如下:
<appSettings> <!----> <!--在Web应用中加载的获取Session的类名称--> <add key="SessionItemName" value="Commercial.Jwsoft.Framework.Persistence.SessionManage.WebNHSession,JWFramework"/> <!--在Windows应用中加载的获取Session的类名称--> <!--<add key="SessionItemName" value="Commercial.Jwsoft.Framework.Persistence.SessionManage.WinFormNHSession,JWFramework"/>--> </appSettings>
在Global.asax中添加如下代码:
/// <summary> /// 当用户断开请求时用来关闭用户请求的Session的连接 /// </summary> /// <param name="sender"></param> /// <param name="e"></param> void Session_End(object sender, EventArgs e) { NHibernate.ISession session = Commercial.Jwsoft.Framework.Persistence.SessionManage.SessionFactory.GetSession(); if (session != null) { session.Close(); }
}
|