简体   繁体   English

Oracle JDBC UCP和Java

[英]Oracle JDBC UCP and Java

I'm wondering if anyone can shed some light on this topic, as I have been racking my brain for days and can't quite understand why this does not work. 我想知道是否有人可以阐明这个话题,因为我已经绞尽脑汁几天了,还不太明白为什么这行不通。 I have three classes main , RetrieveDBVersion , GetOracleConnection I've been doing some testing with oracle JDBC, UCP and Java 1.7. 我有三个类mainRetrieveDBVersionGetOracleConnection我一直在使用oracle JDBC,UCP和Java 1.7进行一些测试。 According to the Oracle documentation, If I use connection pooling the connection will be returned to the pool as soon as I close the connection, Invalidate it and set it to null See Here . 根据Oracle文档,如果我使用连接池的连接将尽快为我关闭连接返回到池中,而无效,并将其设置为null 在这里看到 So I decided to give it a whirl and see if it would perform just like the documentation says it should. 因此,我决定稍加观察一下,看看它是否会像文档所说的那样工作。 In my Main application I have a simple loop which makes a connection 200 times by calling RetrieveDBVersion . 在我的Main应用程序中,我有一个简单的循环,该循环通过调用RetrieveDBVersion 200次连接。 RetrieveDBVersion is simply performing a query and returning the driver version. RetrieveDBVersion只是执行查询并返回驱动程序版本。 My loop works fine until I hit the magic number of 68 and then I receive an error which states 我的循环工作正常,直到我达到神奇的数字68,然后收到一条错误消息,指出

java.sql.SQLException: Exception occurred while getting connection:  
oracle.ucp.UniversalConnectionPoolException:    
Cannot get Connection from Datasource: java.sql.SQLException: 
Listener refused the connection with the following error:
ORA-12516, TNS:listener could not find available handler with matching protocol stack

These are the detail of the 3 methods. 这些是这三种方法的细节。 These methods are not in a server environment. 这些方法不在服务器环境中。 They are simply calling a local oracle express database and I'm running them from my desktop. 他们只是在调用本地oracle express数据库,而我是从桌面运行它们。 Why would I keep getting this error? 为什么我会不断收到此错误? If I'm returning the connections back to the pool? 如果我将连接返回到池中?

  1. Main 主要

     import com.jam.DB.JDBCVersion; import static java.lang.System.out; public class MainApp { public static void main(String[] args) { String myMainJDBCVar; try{ for(int i=1; i<200; i++ ) { myMainJDBCVar= JDBCVersion.RetrieveDBVersion(); out.println(myMainJDBCVar + " " + i); } out.println("this is Done!"); } catch (Exception e) { System.out.println(e.getMessage()); } } } 
  2. RetrieveDBVersion 检索数据库版本

      import java.sql.*; import oracle.ucp.jdbc.ValidConnection; public class JDBCVersion { public static String DBVersion; public static String RetrieveDBVersion()throws SQLException { Connection conn = JDBCConnection.GetOracleConnection("test"); try { DatabaseMetaData meta = conn.getMetaData(); //get driver info System.out.println("JDBC driver version is " + meta.getDriverMajorVersion()); DBVersion = meta.getDriverVersion(); } catch (SQLException e) { e.printStackTrace(); DBVersion = e.getMessage(); } finally { System.out.println("hit the finally clause"); ((ValidConnection) conn).setInvalid(); conn.close(); conn=null; } return DBVersion; } 
  3. GetOracleConnection GetOracleConnection

      import oracle.ucp.jdbc.PoolDataSource; import oracle.ucp.jdbc.PoolDataSourceFactory; import java.sql.*; public class JDBCConnection { public static Connection GetOracleConnection(String Enviroment) throws SQLException{ PoolDataSource pds = PoolDataSourceFactory.getPoolDataSource(); Connection conn = null; //ora.defaultConnection(); try { pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource"); pds.setURL("jdbc:oracle:thin:@//localhost:1521/xe"); pds.setUser("system"); //pds.setInitialPoolSize(5); pds.setPassword("xxx"); pds.setMaxStatements(10); conn = pds.getConnection(); return conn; } catch(Exception e){ e.printStackTrace(); } return conn; } 

So after careful though and getting a little extra help from the Oracle forum. 因此,经过仔细的讨论并从Oracle论坛获得了一些额外的帮助。 I finally understand why the above referenced code is giving the error message that I'm receiving. 我终于明白为什么上面引用的代码给出了我收到的错误消息。 See Here For Response Because I'm setting the data source everytime the loop goes around, I'm essentially creating more than one pool. 请参阅此处以获得响应因为每次循环时都要设置数据源,所以实际上创建了多个池。 The way to do this, is create one pool and than pull connections from that pool. 为此,方法是创建一个池,然后从该池拉连接。 New code to replace the GetOracleConnection I created a singleton class for datasource and in code I simply retrieve the connection from the data source like such 替换GetOracleConnection新代码我为数据源创建了一个单例类,并且在代码中,我像这样从数据源中简单地检索连接

Connection conn = Database.getInstance().GetPoolSource().getConnection();

package com.jam.DB;

import oracle.ucp.jdbc.PoolDataSource;
import oracle.ucp.jdbc.PoolDataSourceFactory;

public class Database {

private static Database dbIsntance;
private static PoolDataSource pds;

private Database() {
    // private constructor //
}

public static Database getInstance() {
    if (dbIsntance == null) {
        dbIsntance = new Database();
    }
    return dbIsntance;
}

public PoolDataSource GetPoolSource() {

    if (pds == null) {
        pds = PoolDataSourceFactory.getPoolDataSource();

        try {

            pds.setConnectionFactoryClassName("oracle.jdbc.pool.OracleDataSource");
            pds.setURL("jdbc:oracle:thin:@//localhost:1521/xe");
            pds.setUser("system");
            pds.setPassword("xxxx");
            pds.setMaxStatements(15);
            return pds;

        } catch (Exception e) {

        }
        return pds;
    }

    return pds;

  }
}

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM