互联网解决方案咨询

梦想有多大路就会有多远:作一颗IT量子
  首页  :: 新随笔  :: 联系 :: 订阅 订阅  :: 管理
在开发社区网站时必须考虑的一个问题是网络用户的并发请求,除了增加Cache和静态化Html的常用手段外,优化Database的tables关系,及SQL 语句也是相当重要,但用户的并发请求Pages,常常会导致一些复杂业务的查询会有可能会出现Sql Connection Time out的错误,用户的并发请求用光了数据库的连接池,怎么办呢,要从根上解决问题是件不太好做的事,涉及的面和相关技术也很多,有数据库结构本身的问题也有代码的问题,也有服务器硬件的问题,但如果出现了以上的问题肯定会出现"红屏",这对于系统来说是一个大禁,这样的用户体验太差了,出现这样的错误对于用户来说是很不爽,对于专业的开发人员肯定认为这个网站技术做的不好,烂,那如何去解决这个问题,直接切入点就是把数据库的连接池管理起来,在代码里控制数据库的接个池大小,而不时由用户直接去请求数据库的连接池,中间业务逻辑上加一层来现对数据库连接的管理。
基本思路是这样,可以用泛型来做一个数据字典,实现对Sqlconnection的集合的维护。
基本过程:
   当用户请求SqlConnection时,先从可用的连接池中取出可用的SqlConnection连接直接返回经人用户,并且把当前正在用的SqlConnection设为锁定不可用状态。如果池中没有任何可用的,那么直接重新生成一个新的SqlConnection.
  当用户用完这个SqlConnection后,把它重新放回到池中等下一次请求。
同样用一个线程去跟踪池中可用连接串的状态,如果它的等待请求时间超过一个时间段如(从它的创建时间到它未使用的间隔时间一分钟未收到用户的请求)那么执行Close方法,让他回收到DataBase的连接池中。
注意ADO.net的SqlConnection的Close方法,其实并不是在物理上关闭连接,你可以用sp_who看是否还存在你的请求,只不过它的状仿是sleeping状态,只有等到没有用户请求,超过了他的过期时间后自动会消失释放资源,当然也可以在c#中释放非托管一SqlConnection资源,要通知GC回收。
DataAccess.ObjectPool.objectPool是用泛型来现实现的一个字典

基本代码如下:
using System;
using System.Collections.Generic;
using System.Text;
using System.Data;
using System.Data.SqlClient;
namespace DataAccess.DbConn
{
    /// <summary>
    /// 数据库连接对象池
    /// </summary>
    public class DBConn : DataAccess.ObjectPool.objectPool<SqlConnection>
    {
        /// <summary>
        /// 私有构造函数
        /// </summary>
        private DBConn()
        {
           
        }
        /// <summary>
        /// 返回自身对象(Singleton)
        /// </summary>
        public static readonly DBConn Instance= new DBConn();

        /// <summary>
        /// 默认连接语句
        /// </summary>
        //public static string DbPoolConnStr = DataAccess.BaseDAO.CONN_STRING_NON_DTC;
        private  string DbPoolConnStr
        {
            get
            {
                return DataAccess.BaseDAO.CONN_STRING_NON_DTC;
            }
        }
        private static int _PoolMaxCount = 10;
        /// <summary>
        /// Gets or sets the pool max count.
        /// </summary>
        /// <value>The pool max count.</value>
        public new  int PoolMaxCount
        {
            get
            {
                return _PoolMaxCount;
            }
            set
            {
                base.PoolMaxCount = _PoolMaxCount;
                _PoolMaxCount = value;
            }
        }
        /// <summary>
        /// 创建数据库连接对象
        /// </summary>
        /// <returns>已打开的数据库连接对象</returns>
        protected override SqlConnection Create()
        {
            SqlConnection conn = new SqlConnection(DbPoolConnStr);
            conn.Open();
            return conn;
        }

        /// <summary>
        /// 验证连接状态
        /// </summary>
        /// <param name="t">数据库连接对象</param>
        /// <returns>连接状态Open : true   Close:false</returns>
        protected override bool ValiDate(SqlConnection t)
        {
            try
            {
                return !(t.State.Equals(ConnectionState.Closed));
            }
            catch (SqlException)
            {
                return false;
            }
        }

        /// <summary>
        /// 关闭数据库连接
        /// </summary>
        /// <param name="t">数据库连接对象</param>
        protected override void Expire(SqlConnection t)
        {
            try
            {
                if (t.State == ConnectionState.Open)
                {
                    t.Close();                 
                }
            }
            catch (SqlException)
            {

            }
        }

        /// <summary>
        /// 从池中获取数据库连接
        /// </summary>
        /// <returns>数据库连接对象</returns>
        public SqlConnection BorrowDBConn()
        {
            try
            {
                return base.GetObjectFromPool();
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        /// <summary>
        /// 将连接对象放入池中
        /// </summary>
        /// <param name="conn">数据库连接对象</param>
        public void ReturnDBConn(SqlConnection conn)
        {
            base.ReturnObjectToPool(conn);
        }
    }
}

因为懂得所以慈悲  leung