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没有销毁,而是放到了连接池中。

原文地址:https://www.cnblogs.com/yaoxc/p/3137374.html