首先说明一下:这个例子是来源于【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类(真的很通用的一个类,设计的很好,感觉可以继承她做任何事)

using System;

using System.Collections;

using System.Timers;

using System.Text;

namespace SqlPool

{

public abstract class ObjectPool

{

///

/// //当前日期时间刻度值,用户判断连接是否超时

///

private long _lastCheckOut;

///

/// 使用对象池

///

private static Hashtable locked;

///

/// 清理对象池

///

private static Hashtable unlocked;

internal static long GARBAGE_INTERVAL = 5 * 1000;

///

/// 构造函数1,说明了两个池是同步的。

///

static ObjectPool()

{

locked = Hashtable.Synchronized(new Hashtable());

unlocked = Hashtable.Synchronized(new Hashtable());

}

///

/// 初始化时间间隔,时间间隔触发事件,释放清理对象池的对象

///

internal ObjectPool()

{

_lastCheckOut = DateTime.Now.Ticks;

System.Timers.Timer aTimer = new System.Timers.Timer();

aTimer.Enabled = true;

aTimer.Interval = GARBAGE_INTERVAL;

aTimer.Elapsed += new ElapsedEventHandler(CollectGarbage);

}

///

/// 建立一个数据库连接

///

///

protected abstract object Create();

///

/// 判断数据库连接是否正常

///

///

///

protected abstract bool Validate(object o);

///

/// 延迟的连接被关闭

///

///

protected abstract void Expire(object o);

///

/// Sql连接超出指定时间后的垃圾回收

///

///

///

private void CollectGarbage(object sender, ElapsedEventArgs ea)

{

lock (this)

{

object o;

long now = DateTime.Now.Ticks;

IDictionaryEnumerator e = unlocked.GetEnumerator();

try {

while (e.MoveNext())

{

o = e.Key;

if(now-((long)unlocked[o])>GARBAGE_INTERVAL)

{

unlocked.Remove(o);

Expire(o);

o = null;

}

}

}

catch{}

}

}

///

/// 获得数据库连接

///

///

internal object GetObjectFromPool()

{

long now = DateTime.Now.Ticks;

_lastCheckOut = now;

object o = null;

lock (this)

{

try

{

foreach (DictionaryEntry myEntry in unlocked)

{

o = myEntry.Key;

if (Validate(o))

{

unlocked.Remove(o);

locked.Add(o, now);

return (o);

}

else

{

unlocked.Remove(o);

Expire(o);

o = null;

}

}

}

catch (Exception) { }

o = Create();

locked.Add(o, now);

}

return o;

}

///

/// 清除数据库连接

///

///

internal void ReturnObjectToPool(object o)

{

if (o != null)

{

lock (this)

{

locked.Remove(o);

unlocked.Add(o, DateTime.Now.Ticks);

}

}

}

}

}

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

using System;

using System.Collections.Generic;

using System.Text;

using System.Data.SqlClient;

namespace SqlPool

{

class DBConnectionSingleton:ObjectPool

{

private DBConnectionSingleton() { }

///

/// 以单例模式创建数据库连接池

///

public static readonly DBConnectionSingleton Instance = new DBConnectionSingleton();

private static string _connectionString = @"Data Source=192.168.168.251/Sql2005;Initial Catalog=XX;User ID=sa;Password=777";

///

/// 数据库连接字符串

///

public static string ConnectionString

{

set {

_connectionString = value;

}

get

{

return _connectionString;

}

}

///

/// 创建数据库连接

///

///

protected override object Create()

{

SqlConnection temp = new SqlConnection(_connectionString);

temp.Open();

return temp;

}

///

/// 判断DB是否已连接

///

///

///

protected override bool Validate(object o)

{

try

{

SqlConnection temp = (SqlConnection)o;

return (!((temp.State.Equals(System.Data.ConnectionState.Closed))));

}

catch

{

return false;

}

}

///

/// 关闭DB连接

///

///

protected override void Expire(object o)

{

try

{

((SqlConnection)o).Close();

}

catch {

}

}

///

/// 获得DB连接

///

///

public SqlConnection BorrowDBConnection()

{

try

{

return ((SqlConnection)base.GetObjectFromPool());

}

catch(Exception e) {

throw e;

}

}

///

/// 清除DB连接

///

///

public void ReturnDBConnecion(SqlConnection e)

{

base.ReturnObjectToPool(e);

}

}

}

3.3 Main函数

using System;

using System.Collections.Generic;

using System.Text;

using System.Data.SqlClient;

namespace SqlPool

{

class Program

{

static void Main(string[] args)

{

DBConnectionSingleton pool;

//获得数据库连接池的单例模式。

pool = DBConnectionSingleton.Instance;

DBConnectionSingleton.ConnectionString = @"Data Source=192.168.168.251/Sql2005;Initial Catalog=XX;User ID=sa;Password=777";

SqlConnection myConnection = pool.BorrowDBConnection();

pool.ReturnDBConnecion(myConnection);

System.Threading.Thread.Sleep(5000);

}

}

}

mysql 连接池 多线程_4 多线程应用:数据库连接池 | 学步园相关推荐

  1. weblogic连接池不释放问题解决_数据库连接池引起的FullGC问题,看我如何一步步排查、分析、解决...

    作者:sneak 链接https://juejin.im/post/5ef800636fb9a07e66233884 来源:掘金 问题现象 在某个工作日,突然收到线上的服务告警,有大量的请求延时产生, ...

  2. mysql数据库资源池是否耗尽_高性能数据库连接池的内幕

    何涛 唯品会平台架构师 何涛,现任职于唯品会平台架构部,要负责数据访问层,网关,数据库中间件,平台框架等开发设计工作.在数据库性能优化,架构设计等方面有着大量的经验积累.热衷于高可用,高并发及高性能的 ...

  3. javaweb mysql 连接池 c3p0 配置_JavaWeb基础—数据库连接池DBCP、C3P0

    一.基本概念 数据库连接池负责分配.管理和释放数据库连接 数据库连接池:(池用map来实现居多) 用处:为了可重用(销毁创建麻烦,开销大)(招培训老师的例子) 二.编写实现数据库连接池 池参数: 初识 ...

  4. mysql连接池_数据库技术:数据库连接池,Commons DbUtils,批处理,元数据

    Database Connection Pool Introduction to Database Connection Pool 实际开发中"获得连接"或"释放资源&q ...

  5. mysql事务锁导致tomcat崩溃_数据库连接池连接耗尽,导致tomcat请求无响应,呈现出假死状态...

    最困难的事情就是认识自己! 个人网站 ,欢迎访问! 前言:最近,测试部门的同事找到我,说他们测试时,没一会就发现服务接口请求一直无响应,Tomcat跟死掉了一样,也没有返回任何的错误响应,说让我赶紧排 ...

  6. mysql连接池和最大连接数_数据库连接池和mysql的最大连接数的区别

    什么叫做数据库连接池 连接池的作用是什么? 数据库连接池,简称dbcp database connection pool 存在意义: 数据库的连接是非常耗费系统资源的,一个应用通常都是需要与数据库打交 ...

  7. java 连接池 druid_从零开始学 Java - 数据库连接池的选择 Druid

    我先说说数据库连接 数据库大家都不陌生,从名字就能看出来它是「存放数据的仓库」,那我们怎么去「仓库」取东西呢?当然需要钥匙啦!这就是我们的数据库用户名.密码了,然后我们就可以打开门去任意的存取东西了. ...

  8. mysql数据库空闲时间设定_关于数据库连接池的最大空闲时间的配置

    关于数据库连接池的最大空闲时间的配置 java的所有的连接池 无论是c3p0.dbcp还是druid,都有一个类似maxIdleTime配置项.具体含义就是当连接长时间没有向服务器发请求的时候,断开这 ...

  9. jsp获取连接池的实时连接数_数据库连接池原理分析及模拟实现

    数据库访问 访问数据库主要有以下几个步骤: 加载数据库驱动 创建数据库连接 执行访问操作并处理执行结果 关闭连接,释放资源 在每一次请求数据库都要经历上述过程,创建连接和释放资源也都是些重复性的动作, ...

最新文章

  1. Ubuntu16.04默认安装了Python2.7和3.5 升级python3.5为3.6
  2. HTML的标签描述7
  3. 从VR到元宇宙:回顾30年,改变虚拟现实的18件大事
  4. Android开发之动态库调用
  5. VR/AR标准委员会成立OpenXR工作组:Oculus、Valve领头
  6. linux自学笔记--nginx基本配置
  7. 众辰变频器参数设定_电工知识:变频器使用方法设定功能参数的方法
  8. MVVM模式的3种command总结[2]--RelayCommand
  9. a开头的计算机语言,我们刚开始接触计算机语言大多从Hello world 开始
  10. Linux vsftpd(ftp)安装包安装方法
  11. 一周试用yii开发一个带各种该有功能的web程序(二)
  12. Excel 枢纽图(Pivot)快速入门与示例
  13. 深度学习自学(十):人脸检测android端-JNI调试调用底层检测识别库
  14. 14Penrose广义逆(II)
  15. 如何解决mysql执行语句效率低下不走索引
  16. MacOS 制作 Linux U盘启动盘
  17. 计算机用word做贺卡,运用Word制作电子贺卡教学设计
  18. docker.socks vul
  19. THE ORDER OF MASS
  20. 微软ASP加密软件 sce10ch

热门文章

  1. matlab 有限元计算
  2. 使用selenium爬取QS世界大学综合排名与学科排名数据
  3. 2021年中国通信基建现状及重点企业:我国5G基站累计建成开通142.5万个,5G投资额达1849亿元[图]
  4. 某查查app sign算法初步探索
  5. java最大公约数最小公倍数的逆问题
  6. 厚物科技PXIe机箱PXI机箱PXIe笔记本HW-19133
  7. web前端学习笔记之Node.js
  8. 什么是防火墙的入站规则和出站规则.如何新建入站规则
  9. ffmepg.exe使用的例子
  10. 运动防水防汗耳机哪个牌子好、最好的防水运动耳机排行推荐