失眠网,内容丰富有趣,生活中的好帮手!
失眠网 > mysql 连接池 多线程_4 多线程应用:数据库连接池 | 学步园

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

时间:2023-12-18 15:05:54

相关推荐

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

首先说明一下:这个例子是来源于【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连接对象的关闭处理。

2UML图例:

这里要说明的是,为什么要继承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/Sql;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/Sql;Initial Catalog=XX;User ID=sa;Password=777";

SqlConnection myConnection = pool.BorrowDBConnection();

pool.ReturnDBConnecion(myConnection);

System.Threading.Thread.Sleep(5000);

}

}

}

如果觉得《mysql 连接池 多线程_4 多线程应用:数据库连接池 | 学步园》对你有帮助,请点赞、收藏,并留下你的观点哦!

本内容不代表本网观点和政治立场,如有侵犯你的权益请联系我们处理。
网友评论
网友评论仅供其表达个人看法,并不表明网站立场。