• ADO.Net连接池


    1、启用了连接池:

    默认情况下ADO.Net启用了连接池《连接池占用本地资源,不是数据库服务器资源,只是当连接池有对象是,数据库服务器要一直打开与相应对象的连接【比如本地连接池中有四个连接对象,那么数据库要打开四个连接保持与本地连接对象的连接】》。

    连接池的缺点就是始终保持与数据库的连接,本地连接池可以设置大小,用于限制连接池中可以存放连接对象的数量。

     1 static void Main(string[] args)
     2         {
     3             //1.启用连接池与禁用连接池为什么性能差距这么大?
     4             //1.当启用连接池后,看似是2000次的登录与注销(连接的打开与关闭),其实只有一次打开,(当程序关闭后才会关闭)。所以高性能
     5 
     6             //2.而禁用连接池后,则是真正的打开关闭了2000次。
     7 
     8             #region 启用连接池
     9 
    10             string constr = "Data Source=zxtiger;Initial Catalog=itcastcn;Integrated Security=True";
    11 
    12             Stopwatch watch = new Stopwatch();
    13             watch.Start();
    14             //执行2000次打开关闭时间---》00:00:00.1383385  
    15             for (int i = 0; i < 2000; i++)
    16             {
    17                 using (SqlConnection con = new SqlConnection(constr))
    18                 {
    19                     con.Open();
    20                     con.Close();
    21                 }
    22             }
    23             watch.Stop();
    24             Console.WriteLine(watch.Elapsed);
    25 
    26             Console.WriteLine("连接打开了又关闭了。");
    27             Console.ReadKey();
    28             #endregion
    29 
    30         }
    31     }

    2、禁用连接池:

     1 static void Main(string[] args)
     2         {
     3             //1.启用连接池与禁用连接池为什么性能差距这么大?
     4             //1.当启用连接池后,看似是2000次的登录与注销(连接的打开与关闭),其实只有一次打开,(当程序关闭后才会关闭)。所以高性能
     5 
     6             //2.而禁用连接池后,则是真正的打开关闭了2000次。
     7             //可以使用SQL SERVER 提供的工具SQL Profiler监测连接情况 
     8         
     9 
    10             #region 禁用连接池后的效果
    11 
    12             string constr = "Data Source=zxtiger;Initial Catalog=itcastcn;Integrated Security=True;Pooling=false";
    13 
    14             Stopwatch watch = new Stopwatch();
    15             watch.Start();
    16             
    17             ////禁用连接池执行2000次用时--》00:00:03.9974913
    18             for (int i = 0; i < 2000; i++)
    19             {
    20                 using (SqlConnection con = new SqlConnection(constr))
    21                 {
    22                     con.Open();
    23                     con.Close();
    24                 }
    25             }
    26             watch.Stop();
    27             Console.WriteLine(watch.Elapsed);
    28 
    29             Console.WriteLine("连接打开了又关闭了。");
    30             Console.ReadKey();
    31             #endregion
    32         }
    33     }

    图中的连接池中存放的是没有被销毁的SqlConncetion对象《该对象已经与数据库建立了连接》,下次再Open()时直接拿来使用,不用再次创建连接。

     证明上图:

    解析:《当con建立与数据库的连接,在对象内部会创建一个和数据库的连接,并把这个连接赋给连接对象内部的一个属性InnerConnection,即:con对象只是对内部InnerConnection对象的包装,其实真正连接数据库的是con内部的InnerConnection对象,接下来我们就可以使用了,使用的时候用的是InnerConnection对象。当我关闭这个连接的时候,即执行con.Close(),其实是把InnerConnection属性放到了连接池中,内部真正访问数据库连接的对象并没有关闭,即InnerConnection并没有关闭,销毁与关闭的都是con对象,当你下次再创建一个连接对象的时候,因为连接字符串和上次的完全相同,虽然创建了一个con对象,但是内部的InnerConnection对象任然使用的是连接池中的InnerConnection对象。由于InnerConnection对象与数据库的连接没有关闭,所以第n(n>1)次使用的时候也就不需要打开了。》

     1 class Program
     2     {
     3         static void Main(string[] args)
     4         {
     5         //默认使用连接池的连接字符串
     6             //string constr = "Data Source=zxtiger;Initial 
     7 
     8 Catalog=itcastcn;Integrated Security=True";
     9             //using (SqlConnection con = new SqlConnection(constr))
    10             //{
    11             //    con.Open();
    12             //}
    13 
    14             //using (SqlConnection con1 = new SqlConnection(constr))
    15             //{
    16             //    con1.Open();
    17             //}//出了作用域自动Dispose
    18 
    19             string constr = "Data Source=zxtiger;Initial 
    20 
    21 Catalog=Itcastcn;Integrated Security=True;Pooling=false";//Pooling=false
    22 
    23 表示禁用连接池
    24    
    25 
    26             //InnerConnection是SqlConnection的私有成员,点不出来,通过反
    27 
    28 射获取...
    29             PropertyInfo pinfo = typeof(SqlConnection).GetProperty
    30 
    31 ("InnerConnection", BindingFlags.NonPublic | BindingFlags.Instance);
    32             SqlConnection con1 = new SqlConnection(constr);
    33             object obj1 = null;
    34             object obj2 = null;
    35 
    36             using (con1)
    37             {
    38                 con1.Open();
    39                 //获取con1内部的InnerConnection对象。
    40                 obj1 = pinfo.GetValue(con1, null);            
    41                 con1.Close();
    42             }
    43 
    44 
    45             // 两次打开同一个连接(因为第二次使用的还是这个连接字符串)
    46             // string constr1 = "Data Source=zxtiger;Initial 
    47 
    48 Catalog=Itcastcn;User ID=sa;Password=124;";
    49             SqlConnection con2 = new SqlConnection(constr);
    50             using (con2)
    51             {
    52                 con2.Open();
    53                 //获取第二个对象的InnerConnection
    54                 obj2 = pinfo.GetValue(con2, null);
    55                 con2.Close();
    56             }
    57     //比较这两个对象是否是同一个对象
    58             if (obj1 == obj2)
    59             {
    60                 Console.WriteLine("是同一个对象");
    61             }
    62             else
    63             {
    64                 Console.WriteLine("不是同一个对象!");
    65             }
    66             Console.ReadKey();
    67 
    68 
    69         }
    70     }

     销毁的是con对象,内部的InnerConnection没有销毁,而是放到了连接池中。

  • 相关阅读:
    简单实用游标更改数据
    C# Http以文件的形式上传文件
    简单例子理解数据库事务
    安卓 隐藏按钮
    jQuery EasyUI API 中文文档
    Linux搭建Tomcat环境
    linux教程之一
    Android服务之PackageManagerService启动源码分析
    DSP、Media、AdExchanger之间的关系及交互流程
    Unity3D中的Coroutine具体解释
  • 原文地址:https://www.cnblogs.com/yaoxc/p/3137374.html
Copyright © 2020-2023  润新知