西西软件园多重安全检测下载网站、值得信赖的软件下载站!
软件
软件
文章
搜索

首页西西教程数据库教程 → 多线程手动创建数据库连接池、减少sql Server的CPU和内存占用

多线程手动创建数据库连接池、减少sql Server的CPU和内存占用

相关软件相关文章发表评论 来源:西西整理时间:2013/2/6 10:14:54字体大小:A-A+

作者:易水寒2012点击:224次评论:1次标签: sqlServer

SQL Server 2017 Developer版64位中文离线安装包
  • 类型:服务器区大小:528.6M语言:多国语言[中文] 评分:10.0
  • 标签:
立即下载

改进前分析:

由于之前做的项目占用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。

贴上部分代码:


 1  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         }




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

    相关评论

    阅读本文后您有什么感想? 已有人给出评价!

    • 8 喜欢喜欢
    • 3 顶
    • 1 难过难过
    • 5 囧
    • 3 围观围观
    • 2 无聊无聊

    热门评论

    最新评论

    发表评论 查看所有评论(1)

    昵称:
    表情: 高兴 可 汗 我不要 害羞 好 下下下 送花 屎 亲亲
    字数: 0/500 (您的评论需要经过审核才能显示)