NHibernate中Session是线程不安全的而且每次数据库操作请求创建Session时对性能有些影响在Windows应用中可以通过 [ThreadStatic]特性很简单的就可以实现线程安全而在Web中可以通过将Session与用于请求HttpContext绑定实现线程安全并且用户当前请求时只有一个Session代码如下
ISessionManagecs
using System;
using NHibernate;
namespace CommercialJwsoftFrameworkPersistenceSessionManage
{
/// <summary>
/// 功能主要用于封装第三方类库操作数据库的Session类现主要用于封装NHibernate中的Session
/// </summary>
public interface ISessionManage
{
/// <summary>
/// 获取Session的一个实例
/// </summary>
/// <returns>返回实现NHibernateISession接口的类</returns>
ISession Get();
/// <summary>
/// 设置Session的一个实例
/// </summary>
/// <param name=session>实现NHibernateISession接口的类</param>
void Set(ISession session);
}
}
--------------------------------------------
WebNHSessioncs
using System;
using SystemWeb;
using NHibernate;
namespace CommercialJwsoftFrameworkPersistenceSessionManage
{
/// <summary>
/// 功能此类用于Web应用NHibernate提供的Session有两个缺陷
/// 一方面是线程不安全的另一方面每次数据库操作创建一个Session对程序性能有影响
/// 因此通过将Session绑定到HttpContext上这样每个用户具有唯一的一个Session而且
/// 在用户的请求结束后关闭Session并自己释放掉
/// </summary>
public class WebNHSession : ISessionManage
{
public WebNHSession()
{
}
/// <summary>
/// 获取存储到HttpContext中的实现NHibernateISession接口的类实例
/// </summary>
/// <returns>实现NHibernateISession接口的类实例当用户之前没有调用Set方法会返回Null</returns>
public ISession Get()
{
return (ISession)HttpContextCurrentItems[SessionConfigManageSessionSourceItemName];
}
/// <summary>
/// 存储实现NHibernateISession接口的类实例到HttpContext中
/// </summary>
/// <param name=session>实现NHibernateISession接口的类实例</param>
public void Set(ISession session)
{
if (session != null)
{
HttpContextCurrentItemsAdd(SessionConfigManageSessionSourceItemName session);
}
else
{
HttpContextCurrentItemsRemove(SessionConfigManageSessionSourceItemName);
}
}
}
}
---------------------------------------------
WinFormNHSessioncs
using System;
using NHibernate;
namespace CommercialJwsoftFrameworkPersistenceSessionManage
{
/// <summary>
/// 功能此类用于Windows应用NHibernate提供的Session有两个缺陷
/// 一方面是线程不安全的另一方面每次数据库操作创建一个Session对程序性能有影响
/// 因此通过线程变量获取一个NHibernate Session的多个线程安全的实例而且线程变量使用后即释放掉
/// </summary>
public class WinFormNHSession : ISessionManage
{
[ThreadStatic]
private static ISession _threadSession = null;
public WinFormNHSession()
{
}
/// <summary>
/// 获取存储到线程变量中的实现NHibernateISession接口的类实例
/// </summary>
/// <returns>实现NHibernateISession接口的线程安全的类实例当用户之前没有调用Set方法会返回Null</returns>
public ISession Get()
{
if (_threadSession != null)
{
if (_threadSessionIsConnected)
{
_threadSessionReconnect();
}
}
return _threadSession;
}
/// <summary>
/// 存储实现NHibernateISession接口的类实例到线程变量中
/// </summary>
/// <param name=session>实现NHibernateISession接口的类实例</param>
public void Set(ISession session)
{
if (_threadSessionIsConnected)
{
sessionDisconnect();
}
_threadSession = session;
}
}
}
SessionFactorycs
using System;
using SystemRuntimeRemoting;
using NHibernate;
namespace CommercialJwsoftFrameworkPersistenceSessionManage
{
/// <summary>
/// 功能管理多个实现ISessionManage接口的类工厂根据读取的要加载的类名称信息进行动态的创建Session
/// </summary>
public class SessionFactory
{
private static ISession session = null;
private static ISessionManage sessionManage = null;
static SessionFactory()
{
Init();
}
/// <summary>
/// 获取实现NHibernateISession接口的Session实例
/// </summary>
/// <returns>返回实现NHibernateISession接口的类实例</returns>
public static ISession GetSession()
{
session = sessionManageGet();
if (session == null)
{
session = NHibernateSessionGetNHibernateSession();
sessionManageSet(session);
}
return session;
}
private static void Init()
{
SystemReflectionAssembly ass = SystemReflectionAssemblyLoad(SessionConfigManageAssemblyName);
sessionManage = (ISessionManage)assCreateInstance(SessionConfigManageSessionSourceItemName);
}
}
}
----------------------------------------------
NHibernateSessioncs
using System;
using SystemData;
using SystemCollectionsGeneric;
using SystemText;
using NHibernate;
using NHibernateCfg;
namespace CommercialJwsoftFrameworkPersistenceSessionManage
{
/// <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 = cfgBuildSessionFactory();
}
/// <summary>
/// 获取NHibernate的Session实例
/// </summary>
/// <returns></returns>
public static ISession GetNHibernateSession()
{
return sessionFactoryOpenSession();
}
}
}
---------------------------------------------
SessionConfigManagecs
using System;
using SystemCollectionsGeneric;
using SystemText;
using SystemConfiguration;
namespace CommercialJwsoftFrameworkPersistenceSessionManage
{
/// <summary>
/// 功能根据类库的应用环境不同(Windows应用还是Web应用)动态创建类实例
/// 日期
/// 作者郭少宏
/// </summary>
public class SessionConfigManage
{
private const string SESSION_ITEM_NAME = SessionItemName;
private static object _locker = new object();
private static string _sessionItemName = stringEmpty;
private static string _assemblyName = stringEmpty;
static SessionConfigManage()
{
string configString = ConfigurationManagerAppSettings[SESSION_ITEM_NAME];
string[] arr = configStringSplit();
_sessionItemName = arr[];
_assemblyName = arr[];
}
/// <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;
}
}
}
}
}
在WebConfig文件中的配置节如下
<appSettings>
<!>
<!在Web应用中加载的获取Session的类名称>
<add key=SessionItemName value=CommercialJwsoftFrameworkPersistenceSessionManageWebNHSessionJWFramework/>
<!在Windows应用中加载的获取Session的类名称>
<!<add key=SessionItemName value=CommercialJwsoftFrameworkPersistenceSessionManageWinFormNHSessionJWFramework/>>
</appSettings>
在Globalasax中添加如下代码
/// <summary>
/// 当用户断开请求时用来关闭用户请求的Session的连接
/// </summary>
/// <param name=sender></param>
/// <param name=e></param>
void Session_End(object sender EventArgs e)
{
NHibernateISession session = CommercialJwsoftFrameworkPersistenceSessionManageSessionFactoryGetSession();
if (session != null)
{
sessionClose();
}
}