精华内容
下载资源
问答
  • 三、数据库连接池工作原理 连接池的工作原理主要由三部分组成,分别为 连接池的建立 连接池中连接的使用管理 连接池的关闭 第一、连接池的建立。 一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了...

    一、什么是连接池?

    数据库连接池负责分配、管理和释放数据库连接,它允许应用程序重复使用一个现有的数据库连接,而不是再重新建立一个;

    释放空闲时间超过最大空闲时间的数据库连接来避免因为没有释放数据库连接而引起的数据库连接遗漏。

    ———以上参考《百度百科》

    二、为什么使用数据连接池

    建立一个数据库连接是一件非常耗时(消耗时间)耗力(消耗资源)的事情。之所以会这样,是因为连接到数据库服务器需要经历几个漫长的过程:建立物理通道(例如套接字或命名管道),与服务器进行初次握手,分析连接字符串信息,由服务器对连接进行身份验证,运行检查以便在当前事务中登记等等。

    连接池就是这样一个容器:它存放了一定数量的与数据库服务器的物理连接。因此,当我们需要连接数据库服务器的时候,只需去池(容器)中取出一条空闲的连接,而不是新建一条连接。这样的话,我们就可以大大减少连接数据库的开销,从而提高了应用程序的性能。

    三、数据库连接池的工作原理

    连接池的工作原理主要由三部分组成,分别为

    • 连接池的建立
    • 连接池中连接的使用管理
    • 连接池的关闭

    第一、连接池的建立。
      一般在系统初始化时,连接池会根据系统配置建立,并在池中创建了几个连接对象,以便使用时能从连接池中获取。连接池中的连接不能随意创建和关闭,这样避免了连接随意建立和关闭造成的系统开销。

    Java中提供了很多容器类可以方便的构建连接池,例如Vector、Stack等。

    第二、连接池的管理。
      连接池管理策略是连接池机制的核心,连接池内连接的分配和释放对系统的性能有很大的影响。其管理策略是:

    当客户请求数据库连接时,

    • 1)如果池中有空闲连接可用,返回该连接。
    • 2)如果没有空闲连接,池中连接都已用完,创建一个新连接添加到池中。
    • 3)如果池中连接已达到最大连接数,请求按设定的最大等待时间进入等待队列直到有空闲连接可用。
    • 4)如果超出最大等待时间,则抛出异常给客户。

    当客户释放数据库连接时,先判断该连接的引用次数是否超过了规定值,如果超过就从连接池中删除该连接,否则保留为其他客户服务。

    该策略保证了数据库连接的有效复用,避免频繁的建立、释放连接所带来的系统资源开销。

    如果连接长时间空闲,或检测到与服务器的连接已断开,连接池管理器也会将该连接从池中移除。

    第三、连接池的关闭。
    当应用程序退出时,关闭连接池中所有的连接,释放连接池相关的资源,该过程正好与创建相反。

    四、连接池需要注意的点

    1、并发问题

    为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。

    这个问题相对比较好解决,因为各个语言自身提供了对并发管理的支持像java,c#等等,使用synchronized(java)lock(C#)关键字即可确保线程是同步的。

    2、事务处理

    我们知道,事务具有原子性,此时要求对数据库的操作符合“ALL-OR-NOTHING”原则,即对于一组SQL语句要么全做,要么全不做。

    我们知道当2个线程共用一个连接Connection对象,而且各自都有自己的事务要处理时候,对于连接池是一个很头疼的问题,因为即使Connection类提供了相应的事务支持,可是我们仍然不能确定那个数据库操作是对应那个事务的,这是由于我们有2个线程都在进行事务操作而引起的。

    为此我们可以使用每一个事务独占一个连接来实现,虽然这种方法有点浪费连接池资源但是可以大大降低事务管理的复杂性。

    3、连接池的分配与释放

    连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。

    对于连接的管理可使用一个List。即把已经创建的连接都放入List中去统一管理。每当用户请求一个连接时,系统检查这个List中有没有可以分配的连接。如果有就把那个最合适的连接分配给他,如果没有就抛出一个异常给用户。

    4、连接池的配置与维护

    连接池中到底应该放置多少连接,才能使系统的性能最佳?

    系统可采取设置**最小连接数(minConnection)最大连接数(maxConnection)**等参数来控制连接池中的连接。

    比方说,最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。

    最大连接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过软件需求上得到。

    如何确保连接池中的最小连接数呢?

    有动态和静态两种策略。
    动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。

    展开全文
  • 连接池的基本工作原理  1、基本概念及原理  由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效...数据库连接池的基本思想就是为数据库连接 建立一个“缓冲池”。预先在缓冲池中放入一定数量的连

      连接池的基本工作原理

      1、基本概念及原理

      由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效管理。我们知道,对于共享资源,有一个很著名的设计模式:资源池 (Resource Pool)。该模式正是为了解决资源的频繁分配?释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接 建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定 连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量?使用情况,为系统开发?测试及性能调 整提供依据。

      2、服务器自带的连接池

      JDBC的API中没有提供连接池的方法。一些大型的WEB应用服务器如BEA的WebLogic和IBM的WebSphere等提供了连接池的机制,但是必须有其第三方的专用类方法支持连接池的用法。

      连接池关键问题分析

      1、并发问题

      为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。这个问题相对比较好解决,因为Java语言自身提供了对并发管理的支 持,使用synchronized关键字即可确保线程是同步的。使用方法为直接在类方法前面加上synchronized关键字,如:

      public synchronized Connection getConnection()

      2、多数据库服务器和多用户

      对于大型的企业级应用,常常需要同时连接不同的数据库(如连接Oracle和Sybase)。如何连接不同的数据库呢?我们采用的策略是:设计 一个符合单例模式的连接池管理类,在连接池管理类的唯一实例被创建时读取一个资源文件,其中资源文件中存放着多个数据库的url地址()?用户名()?密 码()等信息。如 tx.url=172.21.15.123:5000/tx_it,tx.user=yang,tx.password=yang321。根据资源文件提 供的信息,创建多个连接池类的实例,每一个实例都是一个特定数据库的连接池。连接池管理类实例为每个连接池实例取一个名字,通过不同的名字来管理不同的连 接池。

      对于同一个数据库有多个用户使用不同的名称和密码访问的情况,也可以通过资源文件处理,即在资源文件中设置多个具有相同url地址,但具有不同用户名和密码的数据库连接信息。

      3、事务处理

      我们知道,事务具有原子性,此时要求对数据库的操作符合“ALL-ALL-NOTHING”原则,即对于一组SQL语句要么全做,要么全不做。

      在Java语言中,Connection类本身提供了对事务的支持,可以通过设置Connection的AutoCommit属性为 false,然后显式的调用commit或rollback方法来实现。但要高效的进行Connection复用,就必须提供相应的事务支持机制。可采用 每一个事务独占一个连接来实现,这种方法可以大大降低事务管理的复杂性。

      4、连接池的分配与释放

      连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。

      对于连接的管理可使用空闲池。即把已经创建但尚未分配出去的连接按创建时间存放到一个空闲池中。每当用户请求一个连接时,系统首先检查空闲池内 有没有空闲连接。如果有就把建立时间最长(通过容器的顺序存放实现)的那个连接分配给他(实际是先做连接是否有效的判断,如果可用就分配给用户,如不可用 就把这个连接从空闲池删掉,重新检测空闲池是否还有连接);如果没有则检查当前所开连接池是否达到连接池所允许的最大连接数(maxConn),如果没有 达到,就新建一个连接,如果已经达到,就等待一定的时间(timeout)。如果在等待的时间内有连接被释放出来就可以把这个连接分配给等待的用户,如果 等待时间超过预定时间timeout,则返回空值(null)。系统对已经分配出去正在使用的连接只做计数,当使用完后再返还给空闲池。对于空闲连接的状 态,可开辟专门的线程定时检测,这样会花费一定的系统开销,但可以保证较快的响应速度。也可采取不开辟专门线程,只是在分配前检测的方法。

      5、连接池的配置与维护

      连接池中到底应该放置多少连接,才能使系统的性能最佳?系统可采取设置最小连接数(minConn)和最大连接数(maxConn)来控制连接 池中的连接。最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很 快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连 接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过反复测试,找到最佳点。

      如何确保连接池中的最小连接数呢?有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接,以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。

      连接池的实现

      1、连接池模型

      本文讨论的连接池包括一个连接池类(DBConnectionPool)和一个连接池管理类 (DBConnetionPoolManager)。连接池类是对某一数据库所有连接的“缓冲池”,主要实现以下功能:①从连接池获取或创建可用连接;② 使用完毕之后,把连接返还给连接池;③在系统关闭前,断开所有连接并释放连接占用的系统资源;④还能够处理无效连接(原来登记为可用的连接,由于某种原因 不再可用,如超时,通讯问题),并能够限制连接池中的连接总数不低于某个预定值和不超过某个预定值。

      连接池管理类是连接池类的外覆类(wrapper),符合单例模式,即系统中只能有一个连接池管理类的实例。其主要用于对多个连接池对象的管 理,具有以下功能:①装载并注册特定数据库的JDBC驱动程序;②根据属性文件给定的信息,创建连接池对象;③为方便管理多个连接池对象,为每一个连接池 对象取一个名字,实现连接池名字与其实例之间的映射;④跟踪客户使用连接情况,以便需要是关闭连接释放资源。连接池管理类的引入主要是为了方便对多个连接 池的使用和管理,如系统需要连接不同的数据库,或连接相同的数据库但由于安全性问题,需要不同的用户使用不同的名称和密码。

      2、连接池实现

      下面给出连接池类和连接池管理类的主要属性及所要实现的基本接口:

    [java]  view plain copy
    1. public class DBConnectionPool implements TimerListener{  
    2. private int checkedOut;//已被分配出去的连接数  
    3. private ArrayList freeConnections=new ArrayList();  
    4. //容器,空闲池,根据//创建时间顺序存放已创建但尚未分配出去的连接  
    5. private int minConn;//连接池里连接的最小数量  
    6. private int maxConn;//连接池里允许存在的最大连接数  
    7. private String name;//为这个连接池取个名字,方便管理  
    8. private String password;//连接数据库时需要的密码  
    9. private String url;//所要创建连接的数据库的地址  
    10. private String user;//连接数据库时需要的用户名  
    11. public Timer timer;//定时器  
    12. public DBConnectionPool(String name,String URL,String user,  
    13. String password,int maxConn)//公开的构造函数  
    14. public synchronized void freeConnection(Connection con)  
    15. //使用完毕之后,把连接返还给空闲池  
    16. public synchronized Connection getConnection(long timeout)  
    17. //得到一个连接,timeout是等待时间  
    18. public synchronized void release()  
    19. //断开所有连接,释放占用的系统资源  
    20. private Connection newConnection()  
    21. //新建一个数据库连接  
    22. public synchronized void TimerEvent()  
    23. //定时器事件处理函数  
    24. }  
    25. public class DBConnectionManager {  
    26. static private DBConnectionManager instance;  
    27. //连接池管理类的唯一实例  
    28. static private int clients;//客户数量  
    29. private ArrayList drivers=new ArrayList();  
    30. //容器,存放数据库驱动程序  
    31. private HashMap pools = new HashMap();  
    32. //以name/value的形式存取连接池对象的名字及连接池对象  
    33. static synchronized public DBConnectionManager getInstance()  
    34. /**如果唯一的实例instance已经创建,直接返回这个实例;否则,调用私有构造函数, 
    35. 创建连接池管理类的唯一实例*/  
    36. private DBConnectionManager()  
    37. //私有构造函数,在其中调用初始化函数init()  
    38. public void freeConnection(String name,Connection con)  
    39. //释放一个连接,name是一个连接池对象的名字  
    40. public Connection getConnection(String name)  
    41. //从名字为name的连接池对象中得到一个连接  
    42. public Connection getConnection(String name,long time)  
    43. //从名字为name的连接池对象中取得一个连接,time是等待时间  
    44. public synchronized void release()//释放所有资源  
    45. private void createPools(Properties props)  
    46. //根据属性文件提供的信息,创建一个或多个连接池  
    47. private void init()//初始化连接池管理类的唯一实例,由私有构造函数调用  
    48. private void loadDrivers(Properties props)//装载数据库驱动程序  
    49. }  

      3、连接池使用

      上面所实现的连接池在程序开发时如何应用到系统中呢?下面以Servlet为例说明连接池的使用。

      Servlet的生命周期是:在开始建立servlet时,调用其初始化(init)方法。之后每个用户请求都导致一个调用前面建立的实例的service方法的线程。最后,当服务器决定卸载一个servlet时,它首先调用该servlet的destroy方法。

      根据servlet的特点,我们可以在初始化函数中生成连接池管理类的唯一实例(其中包括创建一个或多个连接池)。如:

    [java]  view plain copy
    1. public void init() throws ServletException  
    2. {  
    3. connMgr=DBConnectionManager.getInstance();  
    4. }  
    5. 然后就可以在service方法中通过连接池名称使用连接池,执行数据库操作。最后在destroy方法中释放占用的系统资源,如:  
    6. public void destroy(){  
    7. connMgr.release();  
    8. super.destroy();  
    9. }  

      结束语

      在使用JDBC进行与数据库有关的应用开发中,数据库连接的管理是一个难点。很多时候,连接的混乱管理所造成的系统资源开销过大成为制约大型企 业级应用效率的瓶颈。对于众多用户访问的Web应用,采用数据库连接技术的系统在效率和稳定性上比采用传统的其他方式的系统要好很多。本文阐述了使用 JDBC访问数据库的技术?讨论了基于连接池技术的数据库连接管理的关键问题并给出了一个实现模型。文章所给出的是连接池管理程序的一种基本模式,为提高 系统的整体性能,在此基础上还可以进行很多有意义的扩展。

    展开全文
  • 一个对数据库连接池工作原理的非常详细的解释分析!对他模糊不清的朋友可以一看!
  • 谈谈数据库连接池原理

    万次阅读 多人点赞 2013-11-06 10:14:07
    这次我们采取技术演进的方式来谈谈数据库连接池的技术出现过程及其原理,以及当下最流行的开源数据库连接池jar包。

    谈谈数据库连接池的原理

                                                                                                                                                                             帅宏军

         这次我们采取技术演进的方式来谈谈数据库连接池的技术出现过程及其原理,以及当下最流行的开源数据库连接池jar包。

    一.早期我们怎么进行数据库操作

           1.原理:一般来说,java应用程序访问数据库的过程是:

       ①装载数据库驱动程序;

       ②通过jdbc建立数据库连接;

       ③访问数据库,执行sql语句;

       ④断开数据库连接。

           2.代码 

           // 查询所有用户

           Public void FindAllUsers(){
                  //1、装载sqlserver驱动对象
                  DriverManager.registerDriver(new SQLServerDriver());             
                  //2、通过JDBC建立数据库连接
                  Connection con =DriverManager.getConnection("jdbc:sqlserver://192.168.2.6:1433;DatabaseName=customer", "sa", "123");            
                  //3、创建状态
                  Statement state =con.createStatement();           
                  //4、查询数据库并返回结果
                  ResultSet result =state.executeQuery("select * from users");           
                  //5、输出查询结果
                  while(result.next()){
                         System.out.println(result.getString("email"));
                  }            
                  //6、断开数据库连接
                  result.close();
                  state.close();
                  con.close();
            }

    3.分析

           程序开发过程中,存在很多问题:首先,每一次web请求都要建立一次数据库连接。建立连接是一个费时的活动,每次都得花费0.05s1s的时间,而且系统还要分配内存资源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销。可是对于现在的web应用,尤其是大型电子商务网站,同时有几百人甚至几千人在线是很正常的事。在这种情况下,频繁的进行数据库连接操作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃。不是危言耸听,这就是制约某些电子商务网站发展的技术瓶颈问题。其次,对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。还有,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。

           上述的用户查询案例,如果同时有1000人访问,就会不断的有数据库连接、断开操作:

     

           通过上面的分析,我们可以看出来,“数据库连接”是一种稀缺的资源,为了保障网站的正常使用,应该对其进行妥善管理。其实我们查询完数据库后,如果不关闭连接,而是暂时存放起来,当别人使用时,把这个连接给他们使用。就避免了一次建立数据库连接和断开的操作时间消耗。原理如下:

    二. 技术演进出来的数据库连接池

           由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效管理。我们知道,对于共享资源,有一个很著名的设计模式:资源池(resource pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。

           我们自己尝试开发一个连接池,来为上面的查询业务提供数据库连接服务:

           ①   编写class 实现DataSource 接口

           ②   class构造器一次性创建10个连接,将连接保存LinkedList

           ③   实现getConnection  LinkedList返回一个连接

           ④   提供将连接放回连接池中方法

     

           1、连接池代码       

        public class MyDataSource implements DataSource {
                  //链表 --- 实现栈结构
                  privateLinkedList<Connection> dataSources = new LinkedList<Connection>();
     
                  //初始化连接数量
                  publicMyDataSource() {
                         //一次性创建10个连接
                         for(int i = 0; i < 10; i++) {
                                try {
                                   //1、装载sqlserver驱动对象
                                   DriverManager.registerDriver(new SQLServerDriver());
                                   //2、通过JDBC建立数据库连接
                                   Connection con =DriverManager.getConnection(
                                      "jdbc:sqlserver://192.168.2.6:1433;DatabaseName=customer", "sa", "123");
                                   //3、将连接加入连接池中
                                   dataSources.add(con);
                                } catch (Exception e) {
                                   e.printStackTrace();
                                }
                         }
                  }
     
                  @Override
                  publicConnection getConnection() throws SQLException {
                         //取出连接池中一个连接
                         finalConnection conn = dataSources.removeFirst(); // 删除第一个连接返回
                         returnconn;
                  }
     
                  //将连接放回连接池
                  publicvoid releaseConnection(Connection conn) {
                         dataSources.add(conn);
                         }
           }


           2、使用连接池重构我们的用户查询函数       

           //查询所有用户
           Public void FindAllUsers(){
                  //1、使用连接池建立数据库连接
                  MyDataSource dataSource = new MyDataSource();
                  Connection conn =dataSource.getConnection();        
                  //2、创建状态
                  Statement state =con.createStatement();           
                  //3、查询数据库并返回结果
                  ResultSet result =state.executeQuery("select * from users");           
                  //4、输出查询结果
                  while(result.next()){
                         System.out.println(result.getString("email"));
                  }            
                  //5、断开数据库连接
                  result.close();
                  state.close();
                  //6、归还数据库连接给连接池
                  dataSource.releaseConnection(conn);
            }

           这就是数据库连接池的原理,它大大提供了数据库连接的利用率,减小了内存吞吐的开销。我们在开发过程中,就不需要再关心数据库连接的问题,自然有数据库连接池帮助我们处理,这回放心了吧。但连接池需要考虑的问题不仅仅如此,下面我们就看看还有哪些问题需要考虑。

    三.连接池还要考虑更多的问题

           1、并发问题

           为了使连接管理服务具有最大的通用性,必须考虑多线程环境,即并发问题。这个问题相对比较好解决,因为java语言自身提供了对并发管理的支持,使用synchronized关键字即可确保线程是同步的。使用方法为直接在类方法前面加上synchronized关键字,如:

          publicsynchronized connection getconnection()

     

           2、多数据库服务器和多用户

           对于大型的企业级应用,常常需要同时连接不同的数据库(如连接oraclesybase)。如何连接不同的数据库呢?我们采用的策略是:设计一个符合单例模式的连接池管理类,在连接池管理类的唯一实例被创建时读取一个资源文件,其中资源文件中存放着多个数据库的url地址等信息。根据资源文件提供的信息,创建多个连接池类的实例,每一个实例都是一个特定数据库的连接池。连接池管理类实例为每个连接池实例取一个名字,通过不同的名字来管理不同的连接池。

           对于同一个数据库有多个用户使用不同的名称和密码访问的情况,也可以通过资源文件处理,即在资源文件中设置多个具有相同url地址,但具有不同用户名和密码的数据库连接信息。

     

           3、事务处理

           我们知道,事务具有原子性,此时要求对数据库的操作符合“all-all-nothing”原则即对于一组sql语句要么全做,要么全不做。

           java语言中,connection类本身提供了对事务的支持,可以通过设置connectionautocommit属性为false 然后显式的调用commitrollback方法来实现。但要高效的进行connection复用,就必须提供相应的事务支持机制。可采用每一个事务独占一个连接来实现,这种方法可以大大降低事务管理的复杂性。

     

           4、连接池的分配与释放

           连接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,可以提高连接的复用度,从而降低建立新连接的开销,同时还可以加快用户的访问速度。

           对于连接的管理可使用空闲池。即把已经创建但尚未分配出去的连接按创建时间存放到一个空闲池中。每当用户请求一个连接时,系统首先检查空闲池内有没有空闲连接。如果有就把建立时间最长(通过容器的顺序存放实现)的那个连接分配给他(实际是先做连接是否有效的判断,如果可用就分配给用户,如不可用就把这个连接从空闲池删掉,重新检测空闲池是否还有连接);如果没有则检查当前所开连接池是否达到连接池所允许的最大连接数(maxconn如果没有达到,就新建一个连接,如果已经达到,就等待一定的时间(timeout)。如果在等待的时间内有连接被释放出来就可以把这个连接分配给等待的用户,如果等待时间超过预定时间timeout 则返回空值(null)。系统对已经分配出去正在使用的连接只做计数,当使用完后再返还给空闲池。对于空闲连接的状态,可开辟专门的线程定时检测,这样会花费一定的系统开销,但可以保证较快的响应速度。也可采取不开辟专门线程,只是在分配前检测的方法。

     

           5、连接池的配置与维护

           连接池中到底应该放置多少连接,才能使系统的性能最佳?系统可采取设置最小连接数(minconn)和最大连接数(maxconn)来控制连接池中的连接。最小连接数是系统启动时连接池所创建的连接数。如果创建过多,则系统启动就慢,但创建后系统的响应速度会很快;如果创建过少,则系统启动的很快,响应起来却慢。这样,可以在开发时,设置较小的最小连接数,开发起来会快,而在系统实际使用时设置较大的,因为这样对访问客户来说速度会快些。最大连接数是连接池中允许连接的最大数目,具体设置多少,要看系统的访问量,可通过反复测试,找到最佳点。

           如何确保连接池中的最小连接数呢?有动态和静态两种策略。动态即每隔一定时间就对连接池进行检测,如果发现连接数量小于最小连接数,则补充相应数量的新连接以保证连接池的正常运转。静态是发现空闲连接不够时再去检查。

    四.实际开发中有成熟的开源连接池供我们使用

           理解了连接池的原理就可以了,没有必要什么都从头写一遍,那样会花费很多时间,并且性能及稳定性也不一定满足要求。事实上,已经存在很多流行的性能优良的第三方数据库连接池jar包供我们使用。如:

           1.Apache commons-dbcp 连接池

            下载:http://commons.apache.org/proper/commons-dbcp/

     

           2.c3p0 数据库连接池

            下载:http://sourceforge.net/projects/c3p0/

     

          网上有很多关于这些连接池的介绍文章,这里就不再进行展开。


    转载请注明出处:http://blog.csdn.net/shuaihj/article/details/14223015

    展开全文
  • 数据库连接池原理机制数据库连接池原理机制
  • 数据库连接池原理

    2019-02-28 10:27:00
    数据库连接池原理
  • java实现JDBC数据库连接池原理,里面有oracle驱动jar包,以及代码的阅读步骤
  • 数据库连接池原理机制学习数据库连接池原理机制学习
  • 本篇内容综合广大网友提供内容,笔者经过整理,对数据库连接池原理和实现过程做个很系统的并且通俗易懂的分析讲解,以及手写一个连接池实现过程作为演示。 一、早期通过JDBC方式操作数据库 我们先来看早期使用JDBC...

    本篇内容综合广大网友提供内容,笔者经过整理,对数据库连接池原理和实现过程做个很系统的并且通俗易懂的分析讲解,以及手写一个连接池实现过程作为演示。

    一、早期通过JDBC方式操作数据库

    我们先来看早期使用JDBC的方式操作数据库的过程,这里以mysql数据库为例讲解

    JDBC操作数据库原理:一般来说,java应用程序访问数据库的过程是:

       ①装载数据库驱动程序;

       ②通过jdbc建立数据库连接;

       ③访问数据库,执行sql语句;

       ④断开数据库连接。

    1、具体的代码实现步骤

    创建数据库配置文件db.properties ,配置文件内容如下:

    #连接数据库的url,test表示数据库名,useUnicode=true表示使用Unicode字符集
    url=jdbc:mysql://localhost:3306/test?useUnicode=true&characterEncoding=utf-8; 
    #用户名
    user=root
    #密码
    password=root
    #MySQL数据库加载驱动
    driverClass=com.mysql.jdbc.Driver

    定义一个使用jdbc连接数据库的工具类JdbcUtil.java

    public class JdbcUtil{
        //定义全局变量
        private static String url = null;
        private static String user = null;
        private static String password = null;
        private static driverClass = null;
        //读取配置文件内容,放在静态代码块中就行,因为只需要加载一次就可以了
        static{
            try{
                Properties props = new Properties();
                //使用类路径加载的方式读取配置文件
                //读取的文件路径要以“/”开头,使用"/"开头会直接定位到工程的src路径下
                InputStream in = JdbcUtil.class.getResourceAsStream("/db.properties");
                //加载配置文件
                props.load(in);
                //读取配置文件信息
                url = props.getProperty("url");
                user = props.getProperty("user");
                password = props.getProperty("password");
                driverClass = props.getProperty("driverClass");
                //动态注册mysql驱动程序
                Class.forName(driverClass);
                System.out.println("成功加载MySQL驱动程序");
            }catch(Exception e){
                e.printStackTrace();
                System.out.println("mysql驱动程序注册失败!!!");
            }
        }
    
        //获取连接对象Connection
        public static Connection getConnection(){
            try{
                //要连接数据库,需要向java.sql.DriverManager请求并获得Connection对象
                return DriverManager.getConnection(url,user,password);
            }catch(SQLException e){
                e.printStackTrace();
                //抛出运行时异常
                throw new RuntimeException();
            }
        }
    
        //关闭连接的方法,后打开的先关闭
        public static void close(Connection conn,Statement stmt,ResultSet rs){
            //关闭ResultSet对象
            if(rs != null){
                try{
                    //关闭rs,设置rs=null,因为java会优先回收值为null的变量
                    rs.close();
                    rs = null;
                }catch(SQLException e){
                    e.printStackTrace();
                    throw new RuntimeException();
                }
            }
            //关闭Statement对象,因为PrepareStatement和CallableStatement都是Statement的子接口,所以这里只需要有关闭Statement对象的方法就可以了
            if(stmt != null){
                try{
                    stmt.close();
                    stmt = null;
                }catch(SQLException e){
                    e.printStackTrace();
                    throw new RuntimeException();
                }
            }
            //关闭Connection对象
            if(conn != null){
                try{
                    conn.close();
                    conn = null;
                }catch(SQLException e){
                    e.printStackTrace();
                    throw new RuntimeException();
                }
            }
        }
    }

    到此,这是一个完整的使用JDBC方式操作数据库的过程,下面我们新建一个测试类TestConn.java 测试一下

    package demo;
    
    import java.sql.Connection;
    import java.sql.ResultSet;
    import java.sql.SQLException;
    import java.sql.Statement;
    import utils.JdbcUtil;
    
    public class TestConn {
    
    	public static void main(String[] args) {
    	// TODO Auto-generated method stub
    	Connection conn = JdbcUtil.getConnection();
    	  try {
    		Statement stmt = conn.createStatement();
    		ResultSet rs = stmt.executeQuery("SELECT * FROM user") ;
    		//使用结果集(ResultSet)对象的访问方法获取数据:
    		 while(rs.next()){   
    	         String name = rs.getString("name") ; 
    	         System.out.println(name);
    	         String pass = rs.getString(1);//此方法比较高效,列是从左到右编号的,并且从列1开始 
    	         System.out.println(pass);
    	     } 
    		 //操作完成以后关闭JDBC对象,要把所有使用的JDBC对象全都关闭,以释放JDBC资源,关闭顺序和声明顺序相反: 
    		 //关闭顺序1、关闭记录集,2、关闭声明,3、关闭连接对象
    		 JdbcUtil.close(conn, stmt, rs);
    	  } catch (SQLException e) {
    		// TODO Auto-generated catch block
    		e.printStackTrace();
    	  }
    	}
    }
    

    2、分析

           程序开发过程中,存在很多问题:首先,每一次web请求都要建立一次数据库连接。建立连接是一个费时的活动,每次都得花费0.05s~1s的时间,而且系统还要分配内存资源。这个时间对于一次或几次数据库操作,或许感觉不出系统有多大的开销。可是对于现在的web应用,尤其是大型电子商务网站,同时有几百人甚至几千人在线是很正常的事。在这种情况下,频繁的进行数据库连接操作势必占用很多的系统资源,网站的响应速度必定下降,严重的甚至会造成服务器的崩溃。不是危言耸听,这就是制约某些电子商务网站发展的技术瓶颈问题。其次,对于每一次数据库连接,使用完后都得断开。否则,如果程序出现异常而未能关闭,将会导致数据库系统中的内存泄漏,最终将不得不重启数据库。还有,这种开发不能控制被创建的连接对象数,系统资源会被毫无顾及的分配出去,如连接过多,也可能导致内存泄漏,服务器崩溃。

           上述的用户查询案例,如果同时有1000人访问,就会不断的有数据库连接、断开操作:

    通过上面的分析,我们可以看出来,“数据库连接”是一种稀缺的资源,为了保障网站的正常使用,应该对其进行妥善管理。其实我们查询完数据库后,如果不关闭连接,而是暂时存放起来,当别人使用时,把这个连接给他们使用。就避免了一次建立数据库连接和断开的操作时间消耗。原理如下:

    二、技术演进出来的数据库连接池

           由上面的分析可以看出,问题的根源就在于对数据库连接资源的低效管理。我们知道,对于共享资源,有一个很著名的设计模式:资源池(resource pool)。该模式正是为了解决资源的频繁分配﹑释放所造成的问题。为解决上述问题,可以采用数据库连接池技术。数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接数来防止系统无尽的与数据库连接。更为重要的是我们可以通过连接池的管理机制监视数据库的连接的数量﹑使用情况,为系统开发﹑测试及性能调整提供依据。

           我们自己尝试开发一个连接池,来为上面的查询业务提供数据库连接服务:

           ①   编写class 实现DataSource 接口

           ②   在class构造器一次性创建10个连接,将连接保存LinkedList中

           ③   实现getConnection  从 LinkedList中返回一个连接

           ④   提供将连接放回连接池中方法

    1、实现mysql数据库连接池代码 

    public class MyDataSource implements DataSource {
        //链表实现栈结构
        privateLinkedList<Connection> dataSources = new LinkedList<Connection>();
        //无参构造器,初始化连接数量
        public MyDataSource() {
             //一次性创建10个连接
             for(int i = 0; i < 10; i++) {
                try {
                  //1、获取数据库连接对象
                  Connection conn = JdbcUtil.getConnection();
                  //2、将连接加入连接池中
                  dataSources.add(con);
                } catch (Exception e) {
                  e.printStackTrace();
              }
           }
         }
     
         @Override
         public Connection getConnection() throws SQLException {
             //取出连接池中一个连接
             final Connection conn = dataSources.removeFirst(); //删除第一个连接返回
             return conn;
         }
     
         //将连接放回连接池
         public void releaseConnection(Connection conn) {
             dataSources.add(conn);
         }
    }
    

    这就是数据库连接池的原理,它大大提供了数据库连接的利用率,减小了内存吞吐的开销。我们在开发过程中,我们只关注我们的业务代码的开发,就不需要再关心数据库连接的问题,自然有数据库连接池帮助我们处理。但连接池需要考虑的问题不仅仅如此,还有更多问题需要考虑,在下一节内容中具体分享。

    欢迎广大开发者朋友交流,学习,笔者电话(微信):18629374628

    展开全文
  • 数据库连接池实现原理

    千次阅读 2018-05-08 13:54:10
    为什么要用数据库连接池 数据库连接是一种关键的、有限的、昂贵的资源,这一点在多用户的网页应用程序中体现得尤为突出。对数据库连接的管理能显著影响到整个应用程序的伸缩性和健壮性,影响到程序的性能指标。...
  • Java数据库连接池原理与应用
  • Java数据库连接池原理与应用.pdf
  • java数据库连接池实现原理

    万次阅读 多人点赞 2014-05-10 10:53:53
    一、为什么在连接数据库时要使用连接池 ... 数据库连接池的解决方案是在应用程序启动时建立足够的数据库连接,并讲这些连接组成一个连接池(简单说:在一个“池”里放了好多半成品的数据库联接对象),由应
  • 数据库连接池原理

    2013-11-08 15:01:17
    连接池的基本工作原理  1、基本概念及原理  由上面的分析可以看出,问题的根源就在于对数据库连接资源的...数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要
  • Mybatis深入之数据库连接池原理

    万次阅读 多人点赞 2015-06-23 22:34:43
    Mybatis深入之数据库连接池原理简介主要记录Mybatis数据库连接池实现原理、如何使用连接池来管理数据库连接的、连接池如何向外提供数据库连接、当外部调用使用完成之后是如何将数据库连接放回数据库连接池的。
  • 数据库连接池原理详解与自定义连接池实现

    万次阅读 多人点赞 2017-05-17 18:18:54
    实现原理数据库连接池在初始化时将创建一定数量的数据库连接放到连接池中,这些数据库连接的数量是由最小数据库连接数制约。无论这些数据库连接是否被使用,连接池都将一直保证至少拥有这么多的连接数量。连接池的...
  • 数据库连接池的基本思想是:为数据库连接建立一个...在如今的分布式系统当中,系统的QPS瓶颈往往就在数据库,所以理解数据库连接池底层构造原理与设计思想是很有益处的。 我们常用的数据库连接池有C3P0,DBCP,Dru
  • 数据库连接池的基本原理  传统的数据库连接方式(指通过DriverManager和基本实现DataSource进行连接)中,一个数据库连接对象均对应一个物理数据库连接,数据库连接的建立以及关闭对系统而言是耗费系统资源的操作...
  • 2,数据库连接池的基本思想就是为数据库连接建立一个“缓冲池”。预先在缓冲池中放入一定数量的连接,当需要建立数据库连接时,只需从“缓冲池”中取出一个,使用完毕之后再放回去。我们可以通过设定连接池最大连接...
  • 当客户端请求的数据量比较大的...本文我们主要就介绍一下线程池和数据库连接池原理,接下来我们一起来了解一下这一部分内容。线程池的原理:其实线程池的原理很简单,类似于操作系统中的缓冲区的概念,它的流程如下:

空空如也

空空如也

1 2 3 4 5 ... 20
收藏数 83,357
精华内容 33,342
关键字:

数据库连接池工作原理