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(); } } } |
c#实现用SQL池(多线程),定时批量执行SQL语句的更多相关文章
- c#实现用SQL池(多线程),定时批量执行SQL语句 【转】
在实际项目开发中,业务逻辑层的处理速度往往很快,特别是在开发Socket通信服务的时候,网络传输很快,但是一旦加上数据库操作,性能一落千丈,数据库操作的效率往往成为一个系统整体性能的瓶颈.面对这问题, ...
- SQL Server自动化运维系列——批量执行SQL脚本(Power Shell)
需求描述 一般在生产环境中,在投产的情况下,需要批量的来执行SQL脚本文件,来完成整个投产,如果投产文件比较多的情况下,无疑这是一个比较痛苦的过程,所以本篇通过PowerShell脚本来批量完成. 监 ...
- Jmeter(三十八)Jmeter Question 之 ‘批量执行SQL语句’
知识使我们变得玩世不恭,智慧使我们变得冷酷无情,我们思考的太多,感知太少,除了机器,我们更需要人性,除了智慧,我们需要仁慈和善良. ------出自查理卓别林的演讲 前面有提到Jmeter使用JDBC ...
- PL/SQL中批量执行SQL脚本(不可把所有的语句都复制到New SQL Windows)
PL/SQL中批量执行SQL脚本,不可把所有的语句都复制到New SQL Window,因为这样会导致缓冲区过大而进程卡死! 最好的办法是将要执行的SQL脚本存放到指定文件中,如C:\insert.s ...
- SQL*PLUS中批量执行SQL语句
SQL*PLUS中批量执行SQL语句 今天由于工作的需要,要在CMD中批量执行大量的SQL语句,对于Oracle学习还处在入门阶段的我,只能硬着头皮到处去寻找资料(主要是网络资料,也包括自己的电子书) ...
- 批量执行sql语句
基本使用 $sqls="sql语句1;sql语句2;sql语句n"; 或 $sqls="insert into xx;"; $sqls.="inse ...
- 批量执行SQL文件
原文:批量执行SQL文件 摘要:很多时候我们在做系统升级时需要将大量的.sql文件挨个执行,十分不方便.而且考虑到执行顺序和客服的操作方便性,能不能找到一种简单的方法来批量执行这些sql文件呢? 主要 ...
- jdbc批量执行SQL insert 操作
package com.file; import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayLi ...
- PHP mysqli 增强 批量执行sql 语句的实现代码
本篇文章介绍了,在PHP中 mysqli 增强 批量执行sql 语句的实现代码.需要的朋友参考下. mysqli 增强-批量执行sql 语句 <?php //mysqli 增强-批量执行sql ...
随机推荐
- 遇到问题描述:Android Please ensure that adb is correctly located at问题解决
遇到问题描述: 运行android程序控制台输出 [2013-11-04 16:18:26 - ] The connection to adb is down, and a severe error ...
- SqlServer 在查询结果中如何过滤掉重复数据
问题背景 在一个多表查询的sql中正常情况下产生的数据都是唯一的,但因为数据库中存在错误(某张表中存在相同的外键ID)导致我这边查询出来的数据就会有重复的问题 下面结果集中UserID:15834存在 ...
- Ensemble_learning 集成学习算法 stacking 算法
原文:https://herbertmj.wikispaces.com/stacking%E7%AE%97%E6%B3%95 stacked 产生方法是一种截然不同的组合多个模型的方法,它讲的是组合学 ...
- 拼接多个 wchar_t *
/* wcscat example */ #include <wchar.h> int main () { wchar_t wcs[80]; wcscpy (wcs,L" ...
- 部署项目Nginx+Tornado+Supervisor
http://www.jianshu.com/p/9bebb99368ea Tornado Tornado 和现在的主流 Web 服务器框架(包括大多数 Python 的框架)有着明显的区别:它是非阻 ...
- HIVE部署安装(笔记)
1.下载hive:wget http://mirrors.cnnic.cn/apache/hive/hive-0.12.0/hive-0.12.0.tar.gz2.解压hive安装文件 tar -zv ...
- C#.NET常见问题(FAQ)-找不到类型或命名空间名称“ManagementBaseObject”怎么办
如下图所示,虽然添加了using System.Management,还是报错 System.Management似乎跟普通的命名空间不太一样,这个项目还需要添加.右击这个项目的csproj文件, ...
- redis队列及多线程应用
由于xxx平台上自己的博客已经很久没更新了,一直以来都是用的印象笔记来做工作中知识的积累存根,不知不觉印象笔记里已经有了四.五百遍文章.为了从新开始能与广大攻城狮共同提高技术能力与水平,随决心另起炉灶 ...
- android设备上运行i-jetty服务
android设备上运行i-jetty服务: 1) i-jetty安装 本人小菜一个,i-jetty源码有好几个文件,不知道怎么运行起来,于是找了一个现成可运行的i-jetty工程(感谢这位同学的分享 ...
- Tomcat 设置URI默认字符集为UTF-8
新配置一个Spring的MVC项目.发现对Get请求的中文參数出现了乱码: 查看了SpingMVC中关于编码的配置(在web.xml中).例如以下 <filter> <filter- ...