热门标签 | HotTags
当前位置:  开发笔记 > 数据库 > 正文

c#实现用SQL池,多线程定时批量执行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池代码:

代码如下:

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 pool;

        ///
        /// 初始化SQL池
        ///

        internal SQLPool()
        {
            this.pool = new Stack();
        }

 
        ///
        /// 获取SQL池数量
        ///

        internal Int32 Count
        {
            get { return this.pool.Count; }
        }

 
        ///
        /// 从池中取出SQL
        ///

        ///
        internal string Pop()
        {
            lock (this.pool)
            {
                return this.pool.Pop();
            }
        }

 
        ///
        /// 增加一个SQL到池中
        ///

        ///
        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();
        }

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

        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 构造函数
        ///
        /// 初始化
        ///

        public SQLPoolManage()
        {
            this.poolOfSQL = new SQLPool();
        }
        #endregion

 
        #region 方法
        ///
        /// 将SQL语句加入SQL池中
        ///

        ///
        public void PushSQL(string strSQL)
        {
            this.poolOfSQL.Push(strSQL);
        }

 
        ///
        /// 每隔一段时间,触发ExecuteSQL
        /// ExecuteSQL用于执行SQL池中的SQL语句
        ///

        ///
        public void ExecuteSQL(object obj)
        {
            if (this.poolOfSQL.Count > 0)
            {
                string[] array = this.poolOfSQL.Clear();
                //遍历array,执行SQL
                for (int i = 0; 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();
        }
    }
}


推荐阅读
  • 本文探讨了领域驱动设计(DDD)的核心概念、应用场景及其实现方式,详细介绍了其在企业级软件开发中的优势和挑战。通过对比事务脚本与领域模型,展示了DDD如何提升系统的可维护性和扩展性。 ... [详细]
  • Hadoop入门与核心组件详解
    本文详细介绍了Hadoop的基础知识及其核心组件,包括HDFS、MapReduce和YARN。通过本文,读者可以全面了解Hadoop的生态系统及应用场景。 ... [详细]
  • 探讨如何真正掌握Java EE,包括所需技能、工具和实践经验。资深软件教学总监李刚分享了对毕业生简历中常见问题的看法,并提供了详尽的标准。 ... [详细]
  • 本文详细介绍了如何使用Spring Boot进行高效开发,涵盖了配置、实例化容器以及核心注解的使用方法。 ... [详细]
  • 题库来源:安全生产模拟考试一点通公众号小程序G3锅炉水处理报名考试是安全生产模拟考试一点通生成的,G3锅炉水处理证模拟考试题库是根据G3锅炉水处理最新 ... [详细]
  • 本文详细探讨了Netty中Future及其子类的设计与实现,包括其在并发编程中的作用和具体应用场景。我们将介绍Future的继承体系、关键方法的实现细节,并讨论如何通过监听器和回调机制来处理异步任务的结果。 ... [详细]
  • 2023年京东Android面试真题解析与经验分享
    本文由一位拥有6年Android开发经验的工程师撰写,详细解析了京东面试中常见的技术问题。涵盖引用传递、Handler机制、ListView优化、多线程控制及ANR处理等核心知识点。 ... [详细]
  • 本文介绍如何在 Unity 的 XML 配置文件中,将参数传递给自定义生命周期管理器的构造函数。我们将详细探讨 CustomLifetimeManager 类的实现及其配置方法。 ... [详细]
  • Ralph的Kubernetes进阶之旅:集群架构与对象解析
    本文深入探讨了Kubernetes集群的架构和核心对象,详细介绍了Pod、Service、Volume等基本组件,以及更高层次的抽象如Deployment、StatefulSet等,帮助读者全面理解Kubernetes的工作原理。 ... [详细]
  • 本文详细探讨了Java中StringBuffer类在不同情况下的扩容规则,包括空参构造、带初始字符串和指定初始容量的构造方法。通过实例代码和理论分析,帮助读者更好地理解StringBuffer的内部工作原理。 ... [详细]
  • 深入了解 Windows 窗体中的 SplitContainer 控件
    SplitContainer 控件是 Windows 窗体中的一种复合控件,由两个可调整大小的面板和一个可移动的拆分条组成。本文将详细介绍其功能、属性以及如何通过编程方式创建复杂的用户界面。 ... [详细]
  • 实体映射最强工具类:MapStruct真香 ... [详细]
  • 深入解析 Apache Shiro 安全框架架构
    本文详细介绍了 Apache Shiro,一个强大且灵活的开源安全框架。Shiro 专注于简化身份验证、授权、会话管理和加密等复杂的安全操作,使开发者能够更轻松地保护应用程序。其核心目标是提供易于使用和理解的API,同时确保高度的安全性和灵活性。 ... [详细]
  • 本文探讨了在Linux系统上使用Docker时,通过volume将主机上的HTML5文件挂载到容器内部指定目录时遇到的403错误,并提供了解决方案和详细的操作步骤。 ... [详细]
  • 作为一名专业的Web前端工程师,掌握HTML和CSS的命名规范是至关重要的。良好的命名习惯不仅有助于提高代码的可读性和维护性,还能促进团队协作。本文将详细介绍Web前端开发中常用的HTML和CSS命名规范,并提供实用的建议。 ... [详细]
author-avatar
年轻的蒲山公_777
这个家伙很懒,什么也没留下!
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有