• 多线程环境下,手动创建数据库连接池


    多线程环境下,手动创建数据库连接池

     

    改进前分析:

    由于之前做的项目占用sqlserver太多,程序运行时,导致sqlserver占用CPU 60%左右,内存占用1.6G左右,这种情况下可能会导致服务器的宕机或其它软件无法正常运行。而程序本身并没有占用太多CPU和内存。于是为减少sqlserver的占用,先后使用了两个解决办法:数据库连接池和数据缓冲池。

    由于是在多线程环境下,必须要保证数据同步。而本人对EF没有深入研究,所以只好自己写。

    数据库连接池思路:

    1、当前软件中必须有且只有一个数据库连接池,所以使用单例模式进行定义。

    2、为方便调用,方法使用static定义。

    4、调用DBConnPool(数据库连接池)时,必须保证已经初始化必要的字段,而本类是静态类,所以使用静态构造方法,在静态构造方法中初始化必要的变量。

    3、数据库连接们(sqlconneciton s)必须存储到一个字段中,这个字段是随时增长的(在小于最大连接数时),所以我使用的是List<Sqlconnection>。

    4、一个连接在同一时间只能由一个代码调用,所以必须有属性加以区分,所以封装了自己的mySqlconn,里面包含两个字段:sqlconnection 和bool IsUsed,当 当前连接正在使用时,IsUsed=true,使用完毕IsUsed=false;另外,一般在DBHelper中,我们习惯使用using将sqlconnection包括起来,以便达到手动后释放的效果,这里有两个解决方法: 4.1:mySqlconn实现IDsipose接口,在dispose中 ,将IsUsed设置为false;

         4.2:不适用using,在sqlconnection使用完毕后,调用MySqlconn的Isused设置为false。本人使用的是这种方法。不过这两种理论上都可以。

    5、本程序中没有用到事务处理,所以不对此进行设置,此思路和远吗也仅仅是针对当前项目。

    总结:数据库连接池整个的流程就是

      1、调用DBConnPool(数据库连接池)获取一个数据库连接。

      2、如果是第一次调用则首先调用DBConnPool的静态构造函数,对类进行初始化。

      3、获取数据库连接

        3.1、加锁(线程间同步)

        3.2、从List<MyConn>中获取一个MyConn.IsUsed属性为false的MyConn对象。如果没有则返回Null

        3.2、判断返回的MyConn对象是否为null,如果为null,则判断List<MyConn>.Count是否大于最大数据库连接数,如果大于,则sleep线程,并再次获取,如果小于,则创建新的MyConn对象,并将其放入到List集合中。

        3.3、将得到的MyConn对象的IsUsed设置为true。

        3.4、解锁

        3.5、返回MyConn对象

      4、MyConn对象使用完毕,设置MyConn.IsUsed为false。

    贴上部分代码:

    View Code
     public static MySqlConn GetConn()
     2         {
     3             MySqlConn conn = null;
     4 
     5             lock (syncget)
     6             {
     7                 if (listMySqlConn == null)
     8                 {
     9                     listMySqlConn = new List<MySqlConn>();
    10                 }
    11                 if (listMySqlConn.Count > 0)
    12                 {
    13                     conn = getConnFromCollection();
    14 
    15                     while (conn == null)
    16                     {
    17                         if (listMySqlConn.Count >= maxNum)
    18                         {
    19                             System.Threading.Thread.Sleep(200);
    20                             conn = getConnFromCollection();
    21                         }
    22                         else
    23                         {
    24                             conn = new MySqlConn(listMySqlConn.Count, new SqlConnection(connstr));
    25                             listMySqlConn.Add(conn);
    26                         }
    27                     }
    28                 }
    29                 else
    30                 {
    31                     conn = new MySqlConn(listMySqlConn.Count,new SqlConnection(connstr));
    32                     listMySqlConn.Add(conn);
    33                 }
    34                 conn.IsUsed = true;
    35                 if (conn.Sqlconn.State!=ConnectionState.Open)
    36                 {
    37                     conn.Sqlconn.Open();
    38                 }
    39             }
    40             return conn;
    41         }
    42 
    43         private static MySqlConn getConnFromCollection()
    44         {
    45             MySqlConn conn = null;
    46             foreach (MySqlConn item in listMySqlConn)
    47             {
    48                 if (!item.IsUsed)
    49                 {
    50                     conn = item;
    51                     break;
    52                 }
    53             }
    54             return conn;
    55         }
    复制代码

    这个思路中没有涉及数据库连接池的关闭,由于本人这个项目是定时更新程序,每隔几分钟就要更新一次的,所以没有设定。

    不过可以提供一个思路,在MyConn中增加一个字段LastUseTime,记录本连接上次使用时间。

    在DBConnPool中定义一个System.Threading.Timer 变量,每隔2秒循环当前数据库集合,如果发现当前项上次使用时间距离现在超过5分钟,则将其销毁。(如有更好方法,请告诉我,不胜感激..)

    下一次再写多线程环境下数据缓冲池的

     
     http://www.cnblogs.com/ysh2012/archive/2013/02/06/2900628.html
    分类: C#源码
  • 相关阅读:
    vue相关ajax库的使用
    vue-router核心概念
    Vue.js核心概念
    vue核心概念
    SQL 的各种 JOIN 用法
    应用Itextsharp 添加图片到pdf
    MVC区域路由设置
    LINQ to Entities 不识别方法“System.String ToString()”,因此该方法无法转换为存储表达式。
    使用命令行执行.sql文件
    MVC异常捕获处理,FilterConfig
  • 原文地址:https://www.cnblogs.com/Leo_wl/p/2907902.html
Copyright © 2020-2023  润新知