链接池的基本工做原理

链接池的基本工做原理java

  一、基本概念及原理数据库

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

  二、服务器自带的链接池安全

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

  链接池关键问题分析多线程

  一、并发问题并发

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

  public synchronized Connection getConnection()函数

  二、多数据库服务器和多用户性能

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

  对于同一个数据库有多个用户使用不一样的名称和密码访问的状况,也能够经过资源文件处理,即在资源文件中设置多个具备相同url地址,但具备不一样用户名和密码的数据库链接信息。

  三、事务处理

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

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

  四、链接池的分配与释放

  链接池的分配与释放,对系统的性能有很大的影响。合理的分配与释放,能够提升链接的复用度,从而下降创建新链接的开销,同时还能够加快用户的访问速度。

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

  五、链接池的配置与维护

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

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

  链接池的实现

  一、链接池模型

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

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

  二、链接池实现

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

  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. public class DBConnectionManager { 
  25. static private DBConnectionManager instance; 
  26. //链接池管理类的惟一实例 
  27. static private int clients;//客户数量 
  28. private ArrayList drivers=new ArrayList(); 
  29. //容器,存放数据库驱动程序 
  30. private HashMap pools = new HashMap(); 
  31. //以name/value的形式存取链接池对象的名字及链接池对象 
  32. static synchronized public DBConnectionManager getInstance() 
  33. /**若是惟一的实例instance已经建立,直接返回这个实例;不然,调用私有构造函数,
  34. 建立链接池管理类的惟一实例*/ 
  35. private DBConnectionManager() 
  36. //私有构造函数,在其中调用初始化函数init() 
  37. public void freeConnection(String name,Connection con) 
  38. //释放一个链接,name是一个链接池对象的名字 
  39. public Connection getConnection(String name) 
  40. //从名字为name的链接池对象中获得一个链接 
  41. public Connection getConnection(String name,long time) 
  42. //从名字为name的链接池对象中取得一个链接,time是等待时间 
  43. public synchronized void release()//释放全部资源 
  44. private void createPools(Properties props) 
  45. //根据属性文件提供的信息,建立一个或多个链接池 
  46. private void init()//初始化链接池管理类的惟一实例,由私有构造函数调用 
  47. private void loadDrivers(Properties props)//装载数据库驱动程序 

  三、链接池使用

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

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

  根据servlet的特色,咱们能够在初始化函数中生成链接池管理类的惟一实例(其中包括建立一个或多个链接池)。如:

  1. public void init() throws ServletException 
  2. connMgr=DBConnectionManager.getInstance(); 
  3. 而后就能够在service方法中经过链接池名称使用链接池,执行数据库操做。最后在destroy方法中释放占用的系统资源,如: 
  4. public void destroy(){ 
  5. connMgr.release(); 
  6. super.destroy(); 

  结束语

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

相关文章
相关标签/搜索