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

本文介绍了一个基于C#的数据库连接池设计,采用单例模式和ObjectPool类实现,确保多线程环境下的高效和安全。通过定时器进行连接清理,避免资源浪费,提供获取和归还数据库连接的方法。
摘要由CSDN通过智能技术生成

首先说明一下:这个例子是来源于【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图例:

Snap1.jpg

这里要说明的是,为什么要继承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);

}

}

}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值