当前位置: 移动技术网 > IT编程>开发语言>.net > c#实现用SQL池(多线程),定时批量执行SQL语句 【转】

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

2019年04月04日  | 移动技术网IT编程  | 我要评论

小破孩全集下载,通告格式,天乐宫轮滑新世界

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

  总结有以下三种方法,具体请参见:

方法一:调用线程执行方法,在方法中实现死循环,每个循环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();
        }
    }
}

如对本文有疑问,请在下面进行留言讨论,广大热心网友会与你互动!! 点击进行留言回复

相关文章:

验证码:
移动技术网