主页 > 编程资料 > C# >
发布时间:2015-09-26 作者:网络 阅读:181次
<>

NHibernate中Session是线程不安全的,而且每次数据库操作 请求创建Session时对性能有些影响。在Windows应用中可以通过 [ThreadStatic]特性很简单的就可以实现线程安全,而在Web中可以通过将Session与用于请求HttpContext绑定实现线程安全,并且用户当前请求时只有一个Session。代码如下:

ISessionManage.cs

using System;
using NHibernate;

namespace Commercial.Jwsoft.Framework.Persistence.SessionManage
{
    ///


    /// 功能:主要用于封装第三方类库操作数据库的Session类,现主要用于封装NHibernate中的Session
    ///

    public interface ISessionManage
    {
        ///
        /// 获取Session的一个实例
        ///

        /// 返回实现NHibernate.ISession接口的类
        ISession Get();

        ///


        /// 设置Session的一个实例
        ///

        /// 实现NHibernate.ISession接口的类
        void Set(ISession session);
    }
}

--------------------------------------------

WebNHSession.cs

using System;
using System.Web;
using NHibernate;

namespace Commercial.Jwsoft.Framework.Persistence.SessionManage
{
    ///


    /// 功能:此类用于Web应用,NHibernate提供的Session有两个缺陷:
    ///       一方面是线程不安全的,另一方面每次数据库操作创建一个Session对程序性能有影响。
    ///       因此通过将Session绑定到HttpContext上,这样每个用户具有唯一的一个Session,而且
    ///       在用户的请求结束后关闭Session并自己释放掉。
    ///

    public class WebNHSession : ISessionManage
    {
        public WebNHSession()
        {

        }

        ///


        /// 获取存储到HttpContext中的实现NHibernate.ISession接口的类实例
        ///

        /// 实现NHibernate.ISession接口的类实例,当用户之前没有调用Set方法会返回Null
        public ISession Get()
        {
            return (ISession)HttpContext.Current.Items[SessionConfigManage.SessionSourceItemName];
        }

        ///


        /// 存储实现NHibernate.ISession接口的类实例到HttpContext中
        ///

        /// 实现NHibernate.ISession接口的类实例
        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
{
    ///


    /// 功能:此类用于Windows应用,NHibernate提供的Session有两个缺陷:
    ///       一方面是线程不安全的,另一方面每次数据库操作创建一个Session对程序性能有影响。
    ///       因此通过线程变量获取一个NHibernate Session的多个线程安全的实例,而且线程变量使用后即释放掉。
    ///

    public class WinFormNHSession : ISessionManage
    {
        [ThreadStatic]
        private static ISession _threadSession = null;

        public WinFormNHSession()
        {
        }

        ///


        /// 获取存储到线程变量中的实现NHibernate.ISession接口的类实例
        ///

        /// 实现NHibernate.ISession接口的线程安全的类实例,当用户之前没有调用Set方法会返回Null
        public ISession Get()
        {
            if (_threadSession != null)
            {
                if (_threadSession.IsConnected)
                {
                    _threadSession.Reconnect();
                }
            }
            return _threadSession;
        }

        ///


        /// 存储实现NHibernate.ISession接口的类实例到线程变量中
        ///

        /// 实现NHibernate.ISession接口的类实例
        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
{
    ///


    /// 功能:管理多个实现ISessionManage接口的类工厂,根据读取的要加载的类名称信息,进行动态的创建Session
    ///

    public class SessionFactory
    {
        private static ISession session = null;
        private static ISessionManage sessionManage = null;
       
        static SessionFactory()
        {
            Init();
        }

        ///


        /// 获取实现NHibernate.ISession接口的Session实例
        ///

        /// 返回实现NHibernate.ISession接口的类实例
        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
{
    ///


    /// 功能:加载嵌入资源(Xml配置文件),打开一个SessionFactory,获取NHibernate的Session实例
    ///

    public class NHibernateSession
    {
        private static Configuration cfg = null;
        private static ISessionFactory sessionFactory = null;

        static NHibernateSession()
        {
            cfg = new Configuration().Configure();
            sessionFactory = cfg.BuildSessionFactory();
        }

        ///


        /// 获取NHibernate的Session实例
        ///

        ///
        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
{
    ///


    /// 功能:根据类库的应用环境不同(Windows应用还是Web应用),动态创建类实例
    /// 日期:2006-08-24
    /// 作者:郭少宏
    ///

    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];
        }
        ///


        /// 获取配置文件中名为SESSION_ITEM_NAME配置节的信息,记录的要加载的SessionManage的类全称
        ///

        /// 实现ISessionManage接口的类的名称
        public static string SessionSourceItemName
        {
            get
            {
                lock (_locker)
                {
                    return _sessionItemName;
                }
            }
        }

        ///


        /// 获取配置文件中名为SESSION_ITEM_NAME配置节的信息,记录的要加载的SessionManage的类全称
        ///

        /// 实现ISessionManage接口的类的程序集名称
        public static string AssemblyName
        {
            get
            {
                lock (_locker)
                {
                    return _assemblyName;
                }
            }
        }
    }
}

在Web.Config文件中的配置节如下:


   
   
   
   
   
 

在Global.asax中添加如下代码:

 ///


    /// 当用户断开请求时用来关闭用户请求的Session的连接
    ///

    ///
    ///
  void Session_End(object sender, EventArgs e)
    {
        NHibernate.ISession session = Commercial.Jwsoft.Framework.Persistence.SessionManage.SessionFactory.GetSession();
        if (session != null)
        {
            session.Close();
        }

    }

<> <>
关键字词: