知识大全 Oracle数据库 关于连接池二

Posted

篇首语:不飞则已,一飞冲天;不鸣则已,一鸣惊人。本文由小常识网(cha138.com)小编为大家整理,主要介绍了知识大全 Oracle数据库 关于连接池二相关的知识,希望对你有一定的参考价值。

Oracle数据库 关于连接池二  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!

   * 大连接数为止 在返回连接给客户程序之前 它能够验证连接的有效性    */   class DBConnectionPool    private int checkedOut;   private Vector freeConnections = new Vector();   private int maxConn;   private String name;   private String password;   private String URL;   private String user;      /**   * 创建新的连接池   *   * @param name 连接池名字   * @param URL 数据库的JDBC URL   * @param user 数据库帐号 或 null   * @param password 密码 或 null   * @param maxConn 此连接池允许建立的最大连接数   */   public DBConnectionPool(String name String URL String user String password    int maxConn)    this name = name;   this URL = URL;   this user = user;   this password = password;   this maxConn = maxConn;         /**   * 将不再使用的连接返回给连接池   *   * @param con 客户程序释放的连接   */   public synchronized void freeConnection(Connection con)    // 将指定连接加入到向量末尾   freeConnections addElement(con);   checkedOut ;   notifyAll();         /**   * 从连接池获得一个可用连接 如没有空闲的连接且当前连接数小于最大连接   * 数限制 则创建新连接 如原来登记为可用的连接不再有效 则从向量删除之    * 然后递归调用自己以尝试新的可用连接    */   public synchronized Connection getConnection()    Connection con = null;   if (freeConnections size() > )    // 获取向量中第一个可用连接   con = (Connection) freeConnections firstElement();   freeConnections removeElementAt( );   try    if (con isClosed())    log( 从连接池 + name+ 删除一个无效连接 );   // 递归调用自己 尝试再次获取可用连接   con = getConnection();         catch (SQLException e)    log( 从连接池 + name+ 删除一个无效连接 );   // 递归调用自己 尝试再次获取可用连接   con = getConnection();         else if (maxConn == || checkedOut < maxConn)    con = newConnection();      if (con != null)    checkedOut++;      return con;         /**   * 从连接池获取可用连接 可以指定客户程序能够等待的最长时间\\\\r     * 参见前一个getConnection()方法    *   * @param timeout 以毫秒计的等待时间限制   */   public synchronized Connection getConnection(long timeout)    long startTime = new Date() getTime();   Connection con;   while ((con = getConnection()) == null)    try    wait(timeout);      catch (InterruptedException e)    if ((new Date() getTime() startTime) >= timeout)    // wait()返回的原因是超时   return null;         return con;         /**   * 关闭所有连接   */   public synchronized void release()    Enumeration allConnections = freeConnections elements();   while (allConnections hasMoreElements())    Connection con = (Connection) allConnections nextElement();   try    con close();   log( 关闭连接池 + name+ 中的一个连接 );      catch (SQLException e)    log(e 无法关闭连接池 + name+ 中的连接 );         freeConnections removeAllElements();         /**   * 创建新的连接   */   private Connection newConnection()    Connection con = null;   try    if (user == null)    con = DriverManager getConnection(URL);      else    con = DriverManager getConnection(URL user password);      log( 连接池 + name+ 创建一个新的连接 );      catch (SQLException e)    log(e 无法创建下列URL的连接: + URL);   return null;      return con;             三 类DBConnectionPool说明    该类在 至 行实现 它表示指向某个数据库的连接池 数据库由JDBC URL标识 一个JDBC URL由三部分组成 协议标识(总是jdbc) 驱动程序标识(如 odbc idb oracle等) 数据库标识(其格式依赖于驱动程序) 例如 jdbc:odbc:demo 即是一个指向demo数据库的JDBC URL 而且访问该数据库要使用JDBC ODBC驱动程序 每个连接池都有一个供客户程序使用的名字以及可选的用户帐号 密码 最大连接数限制 如果Web应用程序所支持的某些数据库操作可以被所有用户执行 而其它一些操作应由特别许可的用户执行 则可以为两类操作分别定义连接池 两个连接池使用相同的JDBC URL 但使用不同的帐号和密码     类DBConnectionPool的建构函数需要上述所有数据作为其参数 如 至 行所示 这些数据被保存为它的实例变量     如 至 行 至 行所示 客户程序可以使用DBConnectionPool类提供的两个方法获取可用连接 两者的共同之处在于 如连接池中存在可用连接 则直接返回 否则创建新的连接并返回 如果没有可用连接且已有连接总数等于最大限制数 第一个方法将直接返回null 而第二个方法将等待直到有可用连接为止     所有的可用连接对象均登记在名为freeConnections的向量(Vector)中 如果向量中有多于一个的连接 getConnection()总是选取第一个 同时 由于新的可用连接总是从尾部加入向量 从而使得数据库连接由于长时间闲置而被关闭的风险减低到最小程度     第一个getConnection()在返回可用连接给客户程序之前 调用了isClosed()方法验证连接仍旧有效 如果该连接被关闭或触发异常 getConnection()递归地调用自己以尝试获取另外的可用连接 如果在向量freeConnections中不存在任何可用连接 getConnection()方法检查是否已经指定最大连接数限制 如已经指定 则检查当前连接数是否已经到达极限 此处maxConn为 表示没有限制 如果没有指定最大连接数限制或当前连接数小于该值 该方法尝试创建新的连接 如创建成功 则增加已使用连接的计数并返回 否则返回空值     如 至 行所示 创建新连接由newConnection()方法实现 创建过程与是否已经指定数据库帐号 密码有关     JDBC的DriverManager类提供多个getConnection()方法 这些方法要用到JDBC URL与其它一些参数 如用户帐号和密码等 DriverManager将使用指定的JDBC URL确定适合于目标数据库的驱动程序及建立连接     在 至 行实现的第二个getConnection()方法需要一个以毫秒为单位的时间参数 该参数表示客户程序能够等待的最长时间 建立连接的具体操作仍旧由第一个getConnection()方法实现     该方法执行时先将startTime初始化为当前时间 在while循环中尝试获得一个连接 如果失败 则以给定的时间值为参数调用wait() wait()的返回可能是由于其它线程调用notify()或notifyAll() 也可能是由于预定时间已到 为找出wait()返回的真正原因 程序用当前时间减开始时间(startTime) 如差值大于预定时间则返回空值 否则再次调用getConnection()     把空闲的连接登记到连接池由 至 行的freeConnection()方法实现 它的参数为返回给连接池的连接对象 该对象被加入到freeConnections向量的末尾 然后减少已使用连接计数 调用notifyAll()是为了通知其它正在等待可用连接的线程     许多Servlet引擎为实现安全关闭提供多种方法 数据库连接池需要知道该事件以保证所有连接能够正常关闭 DBConnectionManager类负协调整个关闭过程 但关闭连接池中所有连接的任务则由DBConnectionPool类负责 在 至 行实现的release()方法供DBConnectionManager调用 该方法遍历freeConnections向量并关闭所有连接 然后从向量中删除这些连接      四 类DBConnectionManager 说明\\    该类只能创建一个实例 其它对象能够调用其静态方法(也称为类方法)获得该唯一实例的引用 如 至 行所示 DBConnectionManager类的建构函数是私有的 这是为了避免其它对象创建该类的实例     DBConnectionManager类的客户程序可以调用getInstance()方法获得对该类唯一实例的引用 如 至 行所示 类的唯一实例在getInstance()方法第一次被调用期间创建 此后其引用就一直保存在静态变量instance中 每次调用getInstance()都增加一个DBConnectionManager的客户程序计数 即 该计数代表引用DBConnectionManager唯一实例的客户程序总数 它将被用于控制连接池的关闭操作     该类实例的初始化工作由 至 行之间的私有方法init()完成 其中 getResourceAsStream()方法用于定位并打开外部文件 外部文件的定位方法依赖于类装载器的实现 标准的本地类装载器查找操作总是开始于类文件所在路径 也能够搜索CLASSPATH中声明的路径 db properties是一个属性文件 它包含定义连接池的键 值对 可供定义的公用属性如下     drivers 以空格分隔的JDBC驱动程序类列表  logfile 日志文件的绝对路径    其它的属性和特定连接池相关 其属性名字前应加上连接池名字     < poolname> url 数据库的 JDBC URL  < poolname> maxconn 允许建立的最大连接数 表示没有限制  < poolname> user 用于该连接池的数据库帐号  < poolname> password 相应的密码  其中url属性是必需的 而其它属性则是可选的 数据库帐号和密码必须合法 用于Windows平台的db properties文件示例如下     drivers=sun jdbc odbc JdbcOdbcDriver jdbc idbDriver  logfile=D:\\\\user\\\\src\\\\java\\\\DBConnectionManager\\\\log txt    idb url=jdbc:idb:c:\\\\local\\\\javawebserver \\\\db\\\\db prp  idb maxconn=     access url=jdbc:odbc:demo  access user=demo  access password=demopw    注意在Windows路径中的反斜杠必须输入 个 这是由于属性文件中的反斜杠同时也是一个转义字符     init()方法在创建属性对象并读取db properties文件之后 就开始检查logfile属性 如果属性文件中没有指定日志文件 则默认为当前目录下的DBConnectionManager log文件 如日志文件无法使用 则向System err输出日志记录     装载和注册所有在drivers属性中指定的JDBC驱动程序由 至 行之间的loadDrivers()方法实现 该方法先用StringTokenizer将drivers属性值分割为对应于驱动程序名称的字符串 然后依次装载这些类并创建其实例 最后在 DriverManager中注册该实例并把它加入到一个私有的向量drivers 向量drivers将用于关闭服务时从DriverManager取消所有JDBC 驱动程序的注册     init()方法的最后一个任务是调用私有方法createPools()创建连接池对象 如 至 行所示 createPools()方法先创建所有属性名字的枚举对象(即Enumeration对象 该对象可以想象为一个元素系列 逐次调用其nextElement()方法将顺序返回各元素) 然后在其中搜索名字以 url 结尾的属性 对于每一个符合条件的属性 先提取其连接池名字部分 进而读取所有属于该连接池的属性 最后创建连接池对象并把它保存在实例变量pools中 散列表(Hashtable类 )pools实现连接池名字到连接池对象之间的映射 此处以连接池名字为键 连接池对象为值     为便于客户程序从指定连接池获得可用连接或将连接返回给连接池 类DBConnectionManager提供了方法getConnection()和freeConnection() 所有这些方法都要求在参数中指定连接池名字 具体的连接获取或返回操作则调用对应的连接池对象完成 它们的实现分别在 至 行 至 行 至 行     如 至 行所示 为实现连接池的安全关闭 DBConnectionManager提供了方法release() 在上面我们已经提到 所有DBConnectionManager的客户程序都应该调用静态方法getInstance()以获得该管理器的引用 此调用将增加客户程序计数 客户程序在关闭时调用release()可以递减该计数 当最后一个客户程序调用release() 递减后的引用计数为 就可以调用各个连接池的release()方法关闭所有连接了 管理类release()方法最后的任务是撤销所有JDBC驱动程序的注册      五 Servlet使用连接池示例    Servlet API所定义的Servlet生命周期类如      ) 创建并初始化Servlet(init()方法)    ) 响应客户程序的服务请求(service()方法)    ) Servlet终止运行 释放所有资源(destroy()方法)     本例演示连接池应用 上述关键步骤中的相关操作为      ) 在init() 用实例变量connMgr 保存调用DBConnectionManager getInstance()所返回的引用    ) 在service() 调用getConnection() 执行数据库操作 用freeConnection()将连接返回给连接池    ) 在destroy() 调用release()关闭所有连接 释放所有资源     示例程序清单如下     import java io *;import java sql *;import javax servlet *;import javax servlet *;public class TestServlet extends HttpServlet private DBConnectionManager connMgr; public void init(ServletConfig conf) throws ServletException super init(conf); connMgr = DBConnectionManager getInstance(); public void service(HttpServletRequest req HttpServletResponse res) throws IOException res setContentType( text/ ); PrintWriter out = res getWriter(); Connection con = connMgr getConnection( idb ); if (con == null) out println( 不能获取数据库连接 ); return; ResultSet rs = null; ResultSetMetaData md = null; Statement stmt = null; try stmt = con createStatement(); rs = stmt executeQuery( SELECT * FROM EMPLOYEE ); md = rs getMetaData(); out println( < H >职工数据< /H > ); while (rs next()) out println( < BR> ); for (int i = ; i < md getColumnCount(); i++) out print(rs getString(i) + ); stmt close(); rs close(); catch (SQLException e) e printStackTrace(out); connMgr freeConnection( idb con); public void destroy() connMgr release(); super destroy();    con); public void destroy() connMgr release(); super destroy(); cha138/Article/program/Oracle/201311/17555

相关参考

知识大全 连接oracle的总结(关于tnsname和监听)

该文是我连接oracle的总结特别适合于程序开发人员与oracle菜鸟  如何配置才能使客户端连到数据库要使一个客户端机器能连接oracle数据库需要在客户端机器上安装oracle

知识大全 关于JDBC客户端如何连接ORACLE数据库RAC的负载均衡

关于JDBC客户端如何连接ORACLE数据库RAC的负载均衡  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看

知识大全 关于oracle集群后的weblogic数据源配置

  有两个db做了RAC虚拟路径为ypdbweblogic的数据源连接URL改为下面  当其中一台db挂了保证数据源连接正常  jdbc:oracle:thin:@  (DESCRIPTION=  (

知识大全 通过Oracle连接管理器控制数据库连接

通过Oracle连接管理器控制数据库连接  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  为了更好

知识大全 连接oracle数据库及故障解决办法

  如何配置才能使客户端连到数据库  要使一个客户端机器能连接oracle数据库需要在客户端机器上安装oracle的客户端软件唯一的例外就是java连接数据库的时候可以用jdbcthin模式不用装or

知识大全 通过JDBC连接oracle数据库

通过JDBC连接oracle数据库  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!Java数据库连接

知识大全 Oracle数据库中的(+)连接

Oracle数据库中的(+)连接  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  从表AA(+)=

知识大全 Oracle数据库中的(+)连接如何操作

Oracle数据库中的(+)连接如何操作?  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!  本文主

知识大全 asp.net 连接Oracle数据库

asp.net连接Oracle数据库  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!代码如下&nbs

知识大全 连接Oracle数据库的Hibernate配置文件

连接Oracle数据库的Hibernate配置文件  以下文字资料是由(全榜网网www.cha138.com)小编为大家搜集整理后发布的内容,让我们赶快一起来看一下吧!