您的位置:首页 > 数据库

c#实现用SQL池(多线程),定时批量执行SQL语句

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

(一)SQL池

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

1)internalstringPop(),从池中取出SQL。

2)internalvoidPush(stringitem),增加一个SQL到池中。

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

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

  下面是SQL池代码:

viewsourceprint?

01
using
System;
02
using
System.Collections.Generic;
03
using
System.Linq;
04
using
System.Text;
05
using
System.Threading;
06
07
namespace

Test1
08
{
09
sealed

class
SQLPool

10
{

11
//互斥锁
12
public

static
MutexmutexSQLPool=
new
Mutex();
13
14
//SQL池
15
Stack<
string
>pool;
16
17
///<summary>
18
///初始化SQL池
19
///</summary>
20
internal

SQLPool()
21
{
22
this
.pool=
new
Stack<
string
>();
23
}
24
25
26
///<summary>
27
///获取SQL池数量
28
///</summary>
29
internal

Int32Count
30
{
31
get

{
return
this
.pool.Count;}
32
}
33
34
35
///<summary>
36
///从池中取出SQL
37
///</summary>
38
///<returns></returns>
39
internal

string
Pop()

40
{
41
lock

(
this
.pool)
42
{
43
return

this
.pool.Pop();

44
}
45
}
46
47
48
///<summary>
49
///增加一个SQL到池中
50
///</summary>
51
///<paramname="item"></param>
52
internal

void
Push(
string

item)
53
{
54
if

(item.Trim()==
""
)
55
{
56
throw

new
ArgumentNullException(
"ItemsaddedtoaSQLPoolcannotbenull"
);
57
}
58
59
//此处向SQL池中pushSQL必须与Clear互斥
60
mutexSQLPool.WaitOne();
61
try
62
{
63
this
.pool.Push(item);
//此处如果出错,则不会执行ReleaseMutex,将会死锁
64
}
65
catch
66
{
67
}
68
mutexSQLPool.ReleaseMutex();
69
}
70
71
72
///<summary>
73
///清空SQL池
74
///清空前,返回SQL池中所有SQL语句,
75
///</summary>
76
internal

string
[]Clear()

77
{
78
string
[]array=
new
string
[]{};
79
80
//此处必须与Push互斥
81
mutexSQLPool.WaitOne();
82
try
83
{
84
array=
this
.pool.ToArray();
//此处如果出错,则不会执行ReleaseMutex,将会死锁
85
this
.pool.Clear();
86
}
87
catch
88
{
89
}
90
mutexSQLPool.ReleaseMutex();
91
92
return

array;
93
}
94
}

95
}
(二)SQL池管理

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

  业务逻辑层线程调用publicvoidPushSQL(stringstrSQL)方法,用于向SQL池抛入SQL语句。

  SQL执行线程调用publicvoidExecuteSQL(objectobj)方法,用于批量执行SQL池中的SQL语句。

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

  下面是SQL池管理类代码:

viewsourceprint?

01
using
System;
02
using
System.Collections.Generic;
03
using
System.Linq;
04
using
System.Text;
05
06
namespace

Test1
07
{
08
class

SQLPoolManage
09
{

10
//单例模型
11
public

static
readonly

SQLPoolManagesqlPoolManage=
new

SQLPoolManage();
12
13
#region属性
14
SQLPoolpoolOfSQL;
15
#endregion
16
17
18
#region构造函数
19
///<summary>
20
///初始化
21
///</summary>
22
public

SQLPoolManage()
23
{
24
this
.poolOfSQL=
new
SQLPool();
25
}
26
#endregion
27
28
29
#region方法
30
///<summary>
31
///将SQL语句加入SQL池中
32
///</summary>
33
///<paramname="strSQL"></param>
34
public

void
PushSQL(
string

strSQL)
35
{
36
this
.poolOfSQL.Push(strSQL);
37
}
38
39
40
///<summary>
41
///每隔一段时间,触发ExecuteSQL
42
///ExecuteSQL用于执行SQL池中的SQL语句
43
///</summary>
44
///<paramname="obj"></param>
45
public

void
ExecuteSQL(
object

obj)
46
{
47
if

(
this
.poolOfSQL.Count>0)
48
{
49
string
[]array=
this
.poolOfSQL.Clear();
50
//遍历array,执行SQL
51
for

(
int

i=0;i<array.Length;i++)
52
{
53
if

(array[i].ToString().Trim()!=
""
)
54
{
55
try
56
{
57
//数据库操作
58
//......
59
}
60
catch
61
{
62
}
63
}
64
}
65
}
66
}
67
#endregion
68
69
}

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

  总结有以下三种方法,具体请参见/article/4967043.html:

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

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

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

  代码如下:

viewsourceprint?

01
using
System;
02
using
System.Collections.Generic;
03
using
System.Linq;
04
using
System.Text;
05
06
using
System.Threading;
07
08
namespace

Test1
09
{
10
11
class

Program
12
{

13
static

void
Main(
string
[]args)
14
{
15
//向SQL池中抛入SQL语句
16
SQLPoolManage.sqlPoolManage.PushSQL(
"deletefromtbl_testwhereid=1"
);
17
18
//定时触发SQL执行线程
19
System.Threading.TimerthreadTimer=
new
System.Threading.Timer(
new

System.Threading.TimerCallback(SQLPoolManage.sqlPoolManage.ExecuteSQL),
null
,0,100);
20
21
Console.ReadLine();
22
}
23
}

24
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: