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();
}
}
新聞熱點
疑難解答