4 多线程应用:数据库连接池

转载 2013年12月05日 14:30:29
 

4 多线程应用:数据库连接池

分类: 读书笔记 747人阅读 评论(0) 收藏 举报

首先说明一下:这个例子是来源于【C#线程参考手册】参考手册内的一个例子,在这个我只是想研究一下她的设计原理。

    具体好用不好用,因为没有做具体项目的测试,所以提醒大家注意。     

        

1 设计思路:

   1.1 在程序的全局利用单例模式建立一个数据库连接池对象。

   1.2 获得数据库连接方法BorrowDBConnection()。

        这个方法的作用如下:

             如果【待清理的池】内DB连接对象不是关闭状态,则添加到【DB连接池】,继续使用。

             如果【待清理的池】内DB连接对象是关闭状态,则DB连接被移除【待清理的池】,之后被关闭。

             如果【待清理的池】不存在DB连接对象,则创建DB连接对象后,附加到【DB连接池】内,然后使用她。

  1.3 返回数据库连接给【待清理的池】,方法是ReturnObjectToPool()。

             【DB连接池】删除DB连接对象。

             【待清理的池】追加DB连接对象。

   1.4 延迟DB连接对象的垃圾回收事件

              通过Timer的Elapsed事件,来实现【待清理的池】内的DB连接对象的关闭处理。

 

2 UML图例:

   

   这里要说明的是,为什么要继承ObjectPool类呢?

       因为ObjectPool类的结构对于所有使用池、可手动释放资源的对象是通用的。

 

3 具体代码如下:

     3.1 ObjectPool类(真的很通用的一个类,设计的很好,感觉可以继承她做任何事)

      

[c-sharp] view plaincopy
  1. using System;  
  2. using System.Collections;  
  3. using System.Timers;  
  4. using System.Text;  
  5.   
  6. namespace SqlPool  
  7. {  
  8.     public abstract class ObjectPool  
  9.     {  
  10.         /// <summary>  
  11.         /// //当前日期时间刻度值,用户判断连接是否超时  
  12.         /// </summary>  
  13.         private long _lastCheckOut;  
  14.         /// <summary>  
  15.         /// 使用对象池  
  16.         /// </summary>  
  17.         private static Hashtable locked;   
  18.         /// <summary>  
  19.         /// 清理对象池  
  20.         /// </summary>  
  21.         private static Hashtable unlocked;  
  22.         internal static long GARBAGE_INTERVAL = 5 * 1000;  
  23.   
  24.         /// <summary>  
  25.         /// 构造函数1,说明了两个池是同步的。  
  26.         /// </summary>  
  27.         static ObjectPool()  
  28.         {  
  29.             locked = Hashtable.Synchronized(new Hashtable());  
  30.             unlocked = Hashtable.Synchronized(new Hashtable());  
  31.         }  
  32.   
  33.         /// <summary>  
  34.         /// 初始化时间间隔,时间间隔触发事件,释放清理对象池的对象  
  35.         /// </summary>  
  36.         internal ObjectPool()  
  37.         {  
  38.             _lastCheckOut = DateTime.Now.Ticks;  
  39.             System.Timers.Timer aTimer = new System.Timers.Timer();  
  40.             aTimer.Enabled = true;  
  41.             aTimer.Interval = GARBAGE_INTERVAL;  
  42.             aTimer.Elapsed += new ElapsedEventHandler(CollectGarbage);  
  43.         }  
  44.   
  45.        /// <summary>  
  46.        /// 建立一个数据库连接  
  47.        /// </summary>  
  48.        /// <returns></returns>  
  49.         protected abstract object Create();  
  50.   
  51.         /// <summary>  
  52.         /// 判断数据库连接是否正常  
  53.         /// </summary>  
  54.         /// <param name="o"></param>  
  55.         /// <returns></returns>  
  56.         protected abstract bool Validate(object o);  
  57.   
  58.         /// <summary>  
  59.         /// 延迟的连接被关闭  
  60.         /// </summary>  
  61.         /// <param name="o"></param>  
  62.         protected abstract void Expire(object o);  
  63.   
  64.         /// <summary>  
  65.         /// Sql连接超出指定时间后的垃圾回收  
  66.         /// </summary>  
  67.         /// <param name="sender"></param>  
  68.         /// <param name="ea"></param>  
  69.         private void CollectGarbage(object sender, ElapsedEventArgs ea)  
  70.         {  
  71.             lock (this)  
  72.             {  
  73.                 object o;  
  74.                 long now = DateTime.Now.Ticks;  
  75.                 IDictionaryEnumerator e = unlocked.GetEnumerator();  
  76.   
  77.                 try {  
  78.                     while (e.MoveNext())  
  79.                     {  
  80.                         o = e.Key;  
  81.                         if(now-((long)unlocked[o])>GARBAGE_INTERVAL)  
  82.                         {  
  83.                             unlocked.Remove(o);  
  84.                             Expire(o);  
  85.                             o = null;  
  86.                         }  
  87.                     }  
  88.                 }  
  89.                 catch{}  
  90.             }  
  91.         }  
  92.   
  93.   
  94.         /// <summary>  
  95.         /// 获得数据库连接  
  96.         /// </summary>  
  97.         /// <returns></returns>  
  98.         internal object GetObjectFromPool()  
  99.         {  
  100.             long now = DateTime.Now.Ticks;  
  101.             _lastCheckOut = now;  
  102.             object o = null;  
  103.   
  104.             lock (this)  
  105.             {  
  106.                 try  
  107.                 {  
  108.                     foreach (DictionaryEntry myEntry in unlocked)  
  109.                     {  
  110.                         o = myEntry.Key;  
  111.   
  112.                         if (Validate(o))  
  113.                         {  
  114.                             unlocked.Remove(o);  
  115.                             locked.Add(o, now);  
  116.                             return (o);  
  117.                         }  
  118.                         else  
  119.                         {  
  120.                             unlocked.Remove(o);  
  121.                             Expire(o);  
  122.                             o = null;  
  123.                         }  
  124.                     }  
  125.                 }  
  126.   
  127.                 catch (Exception) { }  
  128.                 o = Create();  
  129.                 locked.Add(o, now);  
  130.             }  
  131.             return o;  
  132.         }  
  133.   
  134.         /// <summary>  
  135.         /// 清除数据库连接  
  136.         /// </summary>  
  137.         /// <param name="o"></param>  
  138.         internal void ReturnObjectToPool(object o)  
  139.         {  
  140.             if (o != null)  
  141.             {  
  142.                 lock (this)  
  143.                 {  
  144.                     locked.Remove(o);  
  145.                     unlocked.Add(o, DateTime.Now.Ticks);  
  146.                 }  
  147.             }  
  148.         }  
  149.     }  
  150. }  

 

    3.2 DBConnectionSingleton类 -   数据库连接池(实现了ObjectPool类的Create,Validate,Expire方法,并使用了单例模式)

    

[c-sharp] view plaincopy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Data.SqlClient;  
  5.   
  6. namespace SqlPool  
  7. {  
  8.     class DBConnectionSingleton:ObjectPool  
  9.     {  
  10.         private DBConnectionSingleton() { }  
  11.   
  12.         /// <summary>  
  13.         /// 以单例模式创建数据库连接池  
  14.         /// </summary>  
  15.         public static readonly DBConnectionSingleton Instance = new DBConnectionSingleton();  
  16.   
  17.         private static string _connectionString = @"Data Source=192.168.168.251/Sql2005;Initial Catalog=XX;User ID=sa;Password=777";  
  18.   
  19.         /// <summary>  
  20.         /// 数据库连接字符串  
  21.         /// </summary>  
  22.         public static string ConnectionString  
  23.         {  
  24.             set {  
  25.                 _connectionString = value;  
  26.             }  
  27.             get  
  28.             {  
  29.                 return _connectionString;  
  30.             }  
  31.         }  
  32.   
  33.         /// <summary>  
  34.         /// 创建数据库连接  
  35.         /// </summary>  
  36.         /// <returns></returns>  
  37.         protected override object Create()  
  38.         {  
  39.             SqlConnection temp = new SqlConnection(_connectionString);  
  40.             temp.Open();  
  41.             return temp;  
  42.         }  
  43.   
  44.         /// <summary>  
  45.         /// 判断DB是否已连接  
  46.         /// </summary>  
  47.         /// <param name="o"></param>  
  48.         /// <returns></returns>  
  49.         protected override bool Validate(object o)  
  50.         {  
  51.             try   
  52.             {  
  53.                 SqlConnection temp = (SqlConnection)o;  
  54.                 return (!((temp.State.Equals(System.Data.ConnectionState.Closed))));  
  55.             }  
  56.             catch  
  57.             {  
  58.                 return false;  
  59.             }  
  60.         }  
  61.   
  62.         /// <summary>  
  63.         /// 关闭DB连接  
  64.         /// </summary>  
  65.         /// <param name="o"></param>  
  66.         protected override void Expire(object o)  
  67.         {  
  68.             try  
  69.             {  
  70.                 ((SqlConnection)o).Close();  
  71.             }  
  72.             catch {   
  73.             }  
  74.         }  
  75.   
  76.         /// <summary>  
  77.         /// 获得DB连接  
  78.         /// </summary>  
  79.         /// <returns></returns>  
  80.         public SqlConnection BorrowDBConnection()  
  81.         {  
  82.             try  
  83.             {  
  84.                 return ((SqlConnection)base.GetObjectFromPool());  
  85.             }  
  86.             catch(Exception e) {  
  87.                 throw e;  
  88.             }  
  89.         }  
  90.   
  91.         /// <summary>  
  92.         /// 清除DB连接  
  93.         /// </summary>  
  94.         /// <param name="e"></param>  
  95.         public void ReturnDBConnecion(SqlConnection e)  
  96.         {  
  97.             base.ReturnObjectToPool(e);  
  98.         }  
  99.     }  
  100. }  

  

     3.3 Main函数

    

[c-sharp] view plaincopy
  1. using System;  
  2. using System.Collections.Generic;  
  3. using System.Text;  
  4. using System.Data.SqlClient;  
  5.   
  6. namespace SqlPool  
  7. {  
  8.     class Program  
  9.     {  
  10.         static void Main(string[] args)  
  11.         {  
  12.             DBConnectionSingleton pool;  
  13.   
  14.             //获得数据库连接池的单例模式。  
  15.             pool = DBConnectionSingleton.Instance;  
  16.               
  17.             DBConnectionSingleton.ConnectionString = @"Data Source=192.168.168.251/Sql2005;Initial Catalog=XX;User ID=sa;Password=777";  
  18.   
  19.             SqlConnection myConnection = pool.BorrowDBConnection();  
  20.             pool.ReturnDBConnecion(myConnection);  
  21.             System.Threading.Thread.Sleep(5000);  
  22.         }  
  23.     }  
  24. }  

    

相关文章推荐

从零开始实现Java多线程数据库连接池(附一个神秘的问题)

本例采用mysql数据库,因此请先下载mysql-connection.jar 众所周知,创建数据库连接需要消耗较多的资源,且创建时间也较长。如果网站一天100万PV(假设每个页面都有DB读取或修改操...
  • soonfly
  • soonfly
  • 2017年05月25日 16:54
  • 2623

java线程池访问mysql数据库

使用dbcp,可以通过线程池的方式访问数据库import org.apache.commons.dbcp.BasicDataSource;import org.apache.commons.loggi...

JAVA数据库连接池实现

连接池的管理用了了享元模式,这里对连接池进行简单设计。 一、设计思路      1.连接池配置属性DBbean:里面存放可以配置的一些属性      2.连接池接口IConnectionPool...

java jdbc线程池的使用

好久没直接使用jdbc了,今天重温了一下相关知识,并对连接池的使用写了简单的示例,记录在此以便需要的同行参考和方便自己查阅,不足之处欢迎批评指正。 1、dbcp数据源 所需jar包 dbcp:连接池的...

Java 数据库连接池、线程池和对象池总结

一、Java数据库连接池总结     数据库连接池的实现及原理         内容摘要: 对于一个复杂的数据库应用,频繁的建立、关闭连接,会极大的减低系统的性能,因为对于连接的使用成了系统性能的...

高并发高效数据库连接池

来源:http://www.lcfms.cn:81/ /*  * 高并发高效数据库连接池  * 作者:老成 http://www.lcfms.cn:81/  */ package c...

线程安全的Mysql数据库连接池

数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏...

Delphi7高级应用开发随书源码

  • 2003年04月30日 00:00
  • 676KB
  • 下载

数据库连接池、静态连接,普通连接的比较2(多线程)

1.前言   本篇文章是继续上一篇针对于多线程情况下对数据库连接池、静态连接和普通连接的测试例子,最后给出这三种方式的比较。 2.使用数据库连接池   1)编写测试类Test.java pub...

高性能数据库连接池的内幕

摘要: 如何打造高性能的数据库连接池框架,可以从哪些角度进行优化,连接池的大量优化实践如何为你的系统保驾护航,本专题将带你走进连接池的世界,为你一一揭晓。 大家可能会有这样疑问:连接池类似于线程...
内容举报
返回顶部
收藏助手
不良信息举报
您举报文章:4 多线程应用:数据库连接池
举报原因:
原因补充:

(最多只允许输入30个字)