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

}

最新文章

  1. Java基础和JDK5.0新特性
  2. noi1696 逆波兰表达式
  3. DML语言练习,数据增删改查,复制清空表
  4. GitHub的使用(下)—— 如何下载一个已存在的 Repository
  5. C++ ADO 数据查询
  6. svn常见问题汇总
  7. JAVA进阶----主线程等待子线程各种方案比较(转)
  8. 剖析html对标准标签和自定义标签闭合与不闭合渲染问题
  9. C#做的颜色工具
  10. El表达式的用法个人总结
  11. Spring源码情操陶冶-AbstractApplicationContext#invokeBeanFactoryPostProcessors
  12. 适配ios11与iphone x实践
  13. HTML DOM 访问2
  14. project1
  15. nodejs-stream部分
  16. linux-文件流4种读取方式
  17. PCA whitening
  18. Vue.js之下拉列表及选中触发事件
  19. LeetCode 141. Linked List Cycle环形链表 (C++)
  20. css零零散散的笔记

热门文章

  1. C++ - 定义无双引号的字符串宏
  2. zeromq学习笔记2——简单的客户端和服务端测试程序
  3. 微信支付WxpayAPI_php_v3 错误修改
  4. 【jQuery Demo】图片瀑布流实现
  5. NPM慢怎么办 - nrm切换资源镜像
  6. MySql之插入操作
  7. ORA-16447 Redo apply was not active at the target standby database
  8. (原)Ring loss Convex Feature Normalization for Face Recognition
  9. 大型互联网架构概述 关于架构的架构目标 典型实现 DNS CDN LB WEB APP SOA MQ CACHE STORAGE
  10. Android--保持加速度传感器在屏幕关闭后运行(收集)