• ADO.NET之连接池


    为什么要使用连接池?

    因为连接数据库是一件非常耗时耗力的一件事。特别影响性能,所以引出了连接池
    连接池是什么?
    存放了一定数量的与数据库服务器的物理连接的容器。当我们需要使用的时候就从容器中取出一条空闲的连接,而不是创建一个新的连接。
    作用:

    减少了连接数据库的开销,提高了性能。
    分类:

    同一时刻,同一应用程序域可以有不同类型的连接池,由链接字符串来区分。打开一条连接,如果这条连接的类型签名与现有的连接不匹配,则创建新的连接池,反之不会创建,共用同一个连接池。
    如何分配连接池?
    在调用Open方法的时候根据连接请求的类型,找到与它相匹配的连接池(根据连接字符串来区分),有则在匹配到的连接池中尽力分配一条空闲的连接。如果已用完则会创建一个新的连接添加到连接池中,如果连接池已达到最大连接数,则会等待,直到有空闲的连接。
    移除无效连接 不能正确的连接到数据库服务器的连接就移除,因为连接池中的连接数量大小有限,所以需要进行移除,否则浪费空间,这是由连接池管理器来处理的。
    回收连接
    使用完的连接应当立即释放或关闭,使用Close或者Dispose方法来实现。
    ADO.Net默认是启用连接池的。连接字符串是可以控制连接池的行为的。比如:
    Max Pool Size:最大连接数,默认100
    Min Pool Size: 最小连接数,默认0
    Pooling 是否启用连接池,默认true,否则设为false。

     测试连接池的存在

    #region 默认启用连接池并且最大数为5
                {
                    string connSQL = @"data source=.;initial catalog=TEST;persist security info=True;
    user id=sa;password=123;MultipleActiveResultSets=True;Max Pool Size=5
    "; for (int i = 0; i < 10; i++) { SqlConnection sqlConnection = new SqlConnection(connSQL); sqlConnection.Open(); Console.WriteLine($"第{i + 1}个链接被打开"); } }

    结果:

    第1个链接被打开
    第2个链接被打开
    第3个链接被打开
    第4个链接被打开
    第5个链接被打开

    所以在开启线程池之后,会遵循设置的连接池的最大数量,因为一直在创建,没有关闭,所以线程池中没有空闲连接了,就只能有5个。

    示例2:不开启线程池

    #region 默认不启用连接池,并且最大数为5  此时设置的最大连接数是无效的了
                {
                    string connSQL = @"data source=.;initial catalog=TEST;
    persist security info=True;user id=sa;password=123;MultipleActiveResultSets=True;Max Pool Size=5;Pooling=false
    "; for (int i = 0; i < 10; i++) { SqlConnection sqlConnection = new SqlConnection(connSQL); sqlConnection.Open(); Console.WriteLine($"第{i + 1}个链接被打开"); } }

    结果:

    第1个链接被打开
    第2个链接被打开
    第3个链接被打开
    第4个链接被打开
    第5个链接被打开
    第6个链接被打开
    第7个链接被打开
    第8个链接被打开
    第9个链接被打开
    第10个链接被打开

    此时这10个连接都不是在连接池中取,全部都是现创建的,设置的最大数量管不了,但是这样的话比如连接池性能很差。

    连接池类别区分测试

    下面connSQL1与connSQL3的内容是一样的,connSQL2多了一个空格

       #region 默认不启用连接池,并且最大数为5  此时设置的最大连接数是无效的了
                {
                    string connSQL1 = @"data source=.;initial catalog=TEST;persist security info=True;user id=sa;password=123;
    MultipleActiveResultSets=True;Max Pool Size=5
    "; string connSQL2 = @" data source=.;initial catalog=TEST;persist security info=True;user id=sa;password=123;
    MultipleActiveResultSets=True;Max Pool Size=5
    "; string connSQL3 = @"data source=.;initial catalog=TEST;persist security info=True;user id=sa;password=123;
    MultipleActiveResultSets=True;Max Pool Size=5
    "; for (int i = 0; i < 5; i++) { SqlConnection sqlConnection1 = new SqlConnection(connSQL1); sqlConnection1.Open(); Console.WriteLine($"connSQL1 第{i + 1}个链接被打开"); SqlConnection sqlConnection2 = new SqlConnection(connSQL2); sqlConnection2.Open(); Console.WriteLine($"connSQL2 第{i + 1}个链接被打开"); SqlConnection sqlConnection3 = new SqlConnection(connSQL3); sqlConnection3.Open(); Console.WriteLine($"connSQL3 第{i + 1}个链接被打开"); } } #endregion

    结果:

    connSQL1 第1个链接被打开
    connSQL2 第1个链接被打开
    connSQL3 第1个链接被打开
    connSQL1 第2个链接被打开
    connSQL2 第2个链接被打开
    connSQL3 第2个链接被打开
    connSQL1 第3个链接被打开
    connSQL2 第3个链接被打开

    并且报了异常:超时已过。 在从池中获取连接之前超时时间已过。 这可能是因为所有池连接都在使用中并且达到了最大池大小

     所以可以证明sqlConnection1和sqlConnection3使用的是同一个连接池,这2个连接已经全部瓜分了5条连接,并且全部都没释放。

    细说数据库连接池

  • 相关阅读:
    2020了,初/中级前端面试你应该知道的(上)
    Vue页面权限控制和动态添加路由
    Javascript获取数组中最大和最小值
    localStorage和cookie的跨域解决方案
    移动端常见问题汇总
    码云git本地仓库链接远程仓库
    IntelliJ IDEA Activation code亲测可用
    Sping4之注入参数
    Sping4之依赖注入
    Spring核心之IOC
  • 原文地址:https://www.cnblogs.com/anjingdian/p/15354679.html
Copyright © 2020-2023  润新知