首页 > 开发 > 综合 > 正文

NHibernate中Session的处理

2024-07-21 02:26:16
字体:
来源:转载
供稿:网友

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();
        }

    }

发表评论 共有条评论
用户名: 密码:
验证码: 匿名发表