手机
当前位置:查字典教程网 >编程开发 >C#教程 >c#实现用SQL池,多线程定时批量执行SQL语句的方法
c#实现用SQL池,多线程定时批量执行SQL语句的方法
摘要:在实际项目开发中,业务逻辑层的处理速度往往很快,特别是在开发Socket通信服务的时候,网络传输很快,但是一旦加上数据库操作,性能一落千丈,...

在实际项目开发中,业务逻辑层的处理速度往往很快,特别是在开发Socket通信服务的时候,网络传输很快,但是一旦加上数据库操作,性能一落千丈,数据库操作的效率往往成为一个系统整体性能的瓶颈。面对这问题,我们怎么办呢?好,下面我就为大家介绍一种方法:构建SQL池,分离业务逻辑层和数据访问层,让业务逻辑层从低效的数据库操作解脱,以提高系统整体性能。

(一)SQL池

SQL池是SQL容器,用于存放业务逻辑层抛过来的SQL语句。SQL池主要提供以下几种方法:

1)internal string Pop(),从池中取出SQL。

2)internal void Push(string item),增加一个SQL到池中。

3)internal string[] Clear(),清空SQL池,清空前,返回SQL池中所有SQL语句。

特别提醒一下,SQL池是面向多线程的,所以必须对公共资源SQL采取锁机制。这里采用互斥锁,当业务逻辑层线程往SQL池中抛入SQL语句时,禁止SQL执行线程执行SQL语句,反之,当SQL执行线程执行SQL语句时,也不允许业务逻辑层线程往SQL池中抛入SQL语句。为什么要这么做?因为SQL执行线程是批量执行SQL语句,在批量执行SQL语句前,会从池中取出所有SQL语句,如果此时业务逻辑层线程往SQL池中抛入SQL语句,则会导致这些SQL语句丢失,得不到执行。

下面是SQL池代码:

复制代码 代码如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

namespace Test1

{

sealed class SQLPool

{

//互斥锁

public static Mutex mutexSQLPool = new Mutex();

//SQL池

Stack<string> pool;

/// <summary>

/// 初始化SQL池

/// </summary>

internal SQLPool()

{

this.pool = new Stack<string>();

}

/// <summary>

/// 获取SQL池数量

/// </summary>

internal Int32 Count

{

get { return this.pool.Count; }

}

/// <summary>

/// 从池中取出SQL

/// </summary>

/// <returns></returns>

internal string Pop()

{

lock (this.pool)

{

return this.pool.Pop();

}

}

/// <summary>

/// 增加一个SQL到池中

/// </summary>

/// <param name="item"></param>

internal void Push(string item)

{

if (item.Trim() == "")

{

throw new ArgumentNullException("Items added to a SQLPool cannot be null");

}

//此处向SQL池中push SQL必须与Clear互斥

mutexSQLPool.WaitOne();

try

{

this.pool.Push(item); //此处如果出错,则不会执行ReleaseMutex,将会死锁

}

catch

{

}

mutexSQLPool.ReleaseMutex();

}

/// <summary>

/// 清空SQL池

/// 清空前,返回SQL池中所有SQL语句,

/// </summary>

internal string[] Clear()

{

string[] array = new string[] { };

//此处必须与Push互斥

mutexSQLPool.WaitOne();

try

{

array = this.pool.ToArray(); //此处如果出错,则不会执行ReleaseMutex,将会死锁

this.pool.Clear();

}

catch

{

}

mutexSQLPool.ReleaseMutex();

return array;

}

}

}

(二)SQL池管理

SQL池管理主要用于管理SQL池,向业务逻辑层线程和SQL执行线程提供接口。

业务逻辑层线程调用 public void PushSQL(string strSQL) 方法,用于向SQL池抛入SQL语句。

SQL执行线程调用 public void ExecuteSQL(object obj) 方法,用于批量执行SQL池中的SQL语句。

注意,SQL池管理类采用单例模型,为什么要采用单例模型?因为SQL池只能存在一个实例,无论是业务逻辑层线程还是SQL执行线程,仅会操作这一个实例,否则,将会导致SQL池不唯一,SQL执行无效。

下面是SQL池管理类代码:

复制代码 代码如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

namespace Test1

{

class SQLPoolManage

{

//单例模型

public static readonly SQLPoolManage sqlPoolManage = new SQLPoolManage();

#region 属性

SQLPool poolOfSQL;

#endregion

#region 构造函数

/// <summary>

/// 初始化

/// </summary>

public SQLPoolManage()

{

this.poolOfSQL = new SQLPool();

}

#endregion

#region 方法

/// <summary>

/// 将SQL语句加入SQL池中

/// </summary>

/// <param name="strSQL"></param>

public void PushSQL(string strSQL)

{

this.poolOfSQL.Push(strSQL);

}

/// <summary>

/// 每隔一段时间,触发ExecuteSQL

/// ExecuteSQL用于执行SQL池中的SQL语句

/// </summary>

/// <param name="obj"></param>

public void ExecuteSQL(object obj)

{

if (this.poolOfSQL.Count > 0)

{

string[] array = this.poolOfSQL.Clear();

//遍历array,执行SQL

for (int i = 0; i < array.Length; i++)

{

if (array[i].ToString().Trim() != "")

{

try

{

//数据库操作

//......

}

catch

{

}

}

}

}

}

#endregion

}

}

(三)定时触发SQL执行线程

总结有以下三种方法:

方法一:调用线程执行方法,在方法中实现死循环,每个循环Sleep设定时间;

方法二:使用System.Timers.Timer类;

方法三:使用System.Threading.Timer;

代码如下:

复制代码 代码如下:

using System;

using System.Collections.Generic;

using System.Linq;

using System.Text;

using System.Threading;

namespace Test1

{

class Program

{

static void Main(string[] args)

{

//向SQL池中抛入SQL语句

SQLPoolManage.sqlPoolManage.PushSQL("delete from tbl_test where id = 1");

//定时触发SQL执行线程

System.Threading.Timer threadTimer = new System.Threading.Timer(new System.Threading.TimerCallback(SQLPoolManage.sqlPoolManage.ExecuteSQL), null, 0, 100);

Console.ReadLine();

}

}

}

【c#实现用SQL池,多线程定时批量执行SQL语句的方法】相关文章:

使用SmtpClient发送邮件的方法

基于一个应用程序多线程误用的分析详解

C#实现通过程序自动抓取远程Web网页信息的代码

c# 重载WndProc,实现重写“最小化”的实现方法

Winform跨线程操作的简单方法

C#访问应用程序配置文件的方法

C#使用DllImport调用非托管的代码的方法

关于C#程序优化的五十种方法

C#中Array与ArrayList用法及转换的方法

使用checked语句防止数据溢出的解决方法

精品推荐
分类导航