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

度往往很快,特别是在开发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池代码:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
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池管理类代码:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
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执行线程

总结有以下三种方法,具体请参见http://www.cnblogs.com/tianzhiliang/archive/2010/08/31/1813928.html

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

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

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

代码如下:

 

?
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
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();
         }
     }
}

<script type="text/javascript"> </script><script type="text/javascript" src="http://pagead2.googlesyndication.com/pagead/show_ads.js"></script>
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值