在实际项目开发中,业务逻辑层的处理速度往往很快,特别是在开发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执行线程

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

方法一:调用线程执行方法,在方法中实现死循环,每个循环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语句 【转】的更多相关文章

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

    在实际项目开发中,业务逻辑层的处理速度往往很快,特别是在开发Socket通信服务的时候,网络传输很快,但是一旦加上数据库操作,性能一落千丈,数据库操作的效率往往成为一个系统整体性能的瓶颈.面对这问题, ...

  2. SQL Server自动化运维系列——批量执行SQL脚本(Power Shell)

    需求描述 一般在生产环境中,在投产的情况下,需要批量的来执行SQL脚本文件,来完成整个投产,如果投产文件比较多的情况下,无疑这是一个比较痛苦的过程,所以本篇通过PowerShell脚本来批量完成. 监 ...

  3. Jmeter(三十八)Jmeter Question 之 ‘批量执行SQL语句’

    知识使我们变得玩世不恭,智慧使我们变得冷酷无情,我们思考的太多,感知太少,除了机器,我们更需要人性,除了智慧,我们需要仁慈和善良. ------出自查理卓别林的演讲 前面有提到Jmeter使用JDBC ...

  4. PL/SQL中批量执行SQL脚本(不可把所有的语句都复制到New SQL Windows)

    PL/SQL中批量执行SQL脚本,不可把所有的语句都复制到New SQL Window,因为这样会导致缓冲区过大而进程卡死! 最好的办法是将要执行的SQL脚本存放到指定文件中,如C:\insert.s ...

  5. SQL*PLUS中批量执行SQL语句

    SQL*PLUS中批量执行SQL语句 今天由于工作的需要,要在CMD中批量执行大量的SQL语句,对于Oracle学习还处在入门阶段的我,只能硬着头皮到处去寻找资料(主要是网络资料,也包括自己的电子书) ...

  6. 批量执行sql语句

    基本使用 $sqls="sql语句1;sql语句2;sql语句n"; 或 $sqls="insert into xx;";  $sqls.="inse ...

  7. 批量执行SQL文件

    原文:批量执行SQL文件 摘要:很多时候我们在做系统升级时需要将大量的.sql文件挨个执行,十分不方便.而且考虑到执行顺序和客服的操作方便性,能不能找到一种简单的方法来批量执行这些sql文件呢? 主要 ...

  8. jdbc批量执行SQL insert 操作

    package com.file; import java.io.BufferedReader; import java.io.FileReader; import java.util.ArrayLi ...

  9. PHP mysqli 增强 批量执行sql 语句的实现代码

    本篇文章介绍了,在PHP中 mysqli 增强 批量执行sql 语句的实现代码.需要的朋友参考下. mysqli 增强-批量执行sql 语句 <?php //mysqli 增强-批量执行sql ...

随机推荐

  1. 第9章 设备授权端点(Device Authorization Endpoint) - IdentityModel 中文文档(v1.0.0)

    OAuth 2.0设备流设备授权的客户端库是作为HttpClient扩展方法提供的. 以下代码发送设备授权请求: var client = new HttpClient(); var response ...

  2. .net MVC +EF+VUE做回合制游戏(一)

    刚毕业的新人,工作的时候试过用.net 框架,但是我发现写的前端代码都非常多,要写很多很多的原生,然后最近在看vue.js觉得还不错,可以减少前端很多dom操作. 至于做的东西我是想做一个游戏,一个回 ...

  3. Hystrix源码解析

    1. Hystrix源码解析 1.1. @HystrixCommand原理 直接通过Aspect切面来做的 1.2. feign hystrix原理 它的本质原理就是对HystrixCommand的动 ...

  4. JAVA_OPTS设置

    AVA_OPTS ,顾名思义,是用来设置JVM相关运行参数的变量. JVM:JAVA_OPTS="-server -Xms2048m -Xmx2048m -Xss512k" -se ...

  5. gulp源码解析(一)—— Stream详解

    作为前端,我们常常会和 Stream 有着频繁的接触.比如使用 gulp 对项目进行构建的时候,我们会使用 gulp.src 接口将匹配到的文件转为 stream(流)的形式,再通过 .pipe() ...

  6. 使用 Parallels Destop 最小化安装 centOS 操作系统

    1. 环境准备 macOS 操作系统 Parallels Destop 13 CentOS 7.6 Minimal ISO 镜像文件 2. 新建操作系统 选择下载好的 CentosOS 7.6 即 C ...

  7. CopyOnWriteArrayList源码解析

    Java并发包提供了很多线程安全的集合,有了他们的存在,使得我们在多线程开发下,可以和单线程一样去编写代码,大大简化了多线程开发的难度,但是如果不知道其中的原理,可能会引发意想不到的问题,所以知道其中 ...

  8. IDEA同步上传lua代码,方便开发。

    因项目是Java和lua一起开发的,以前用Notepad++插件连接,每次关掉得重新寻找目录.有点耗时间,所以用idea提供的工具很是便利,再此做个笔记. 点击上面的绿色”+“号,添加 在配置mapp ...

  9. python接口自动化(十一)--发送post【data】(详解)

    简介 前面登录博客园的是传 json 参数,由于其登录机制的改变没办法演示,然而在工作中有些登录不是传 json 的,如 jenkins 的登录,这里小编就以jenkins 登录为案例,传 data ...

  10. 深入学习ThreadLocal原理

    上文我们学习了ThreadLocal的基本用法以及基本原理,ThreadLocal中的方法并不多,基本用到的也就get.set.remove等方法,但是其核心逻辑还是在定义在ThreadLocal内部 ...