Warning: file_get_contents(/data/phpspider/zhask/data//catemap/5/sql/71.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Java 我是否正确关闭此Oracle池连接?_Java_Sql_Database_Oracle - Fatal编程技术网

Java 我是否正确关闭此Oracle池连接?

Java 我是否正确关闭此Oracle池连接?,java,sql,database,oracle,Java,Sql,Database,Oracle,我正试图用Java为我的web应用程序使用池连接。我正在使用Oracle数据库,以下是我的代码: public class DatabaseHandler { static private Connection m_database = null; static private OracleConnectionPoolDataSource pooledSource = null; /** * Attempts to open an Oracle datab

我正试图用Java为我的web应用程序使用池连接。我正在使用Oracle数据库,以下是我的代码:

public class DatabaseHandler
{

    static private Connection m_database = null;

    static private OracleConnectionPoolDataSource pooledSource = null;

    /**
     * Attempts to open an Oracle database located at the specified serverName and port.
     * @param serverName Address of the server.
     * @param portNumber Port to connect to.
     * @param sid SID of the server.
     * @param userName Username to login with.
     * @param password Password to login with.
     * @throws WebApplicationException with response code 500 Internal Server Error.
     */
    static public void openDatabase(String userName, String password,String serverName,int portNumber, String sid)
    throws WebApplicationException
    {
        try
        {
            // Load the JDBC driver
            String driverName = "oracle.jdbc.driver.OracleDriver";
            Class.forName(driverName);

            // Create a connection to the database
            String url = "jdbc:oracle:thin:@" + serverName + ":" + portNumber + ":" + sid;
            pooledSource = new OracleConnectionPoolDataSource();

            pooledSource.setUser(userName);
            pooledSource.setURL(url);
            pooledSource.setPassword(password);
            m_database = pooledSource.getConnection();

        }
        catch (ClassNotFoundException e) 
        {
            // Could not find the database driver
            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        }
        catch (SQLException e) 
        {
            // Could not connect to the database
            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        }
    }


    /**
     * Attempts to execute the specified SQL query.
     * @throws WebApplicationException with a response code of Bad Request
     * if the query is invalid SQL.
     */
    static public ResultSet makeQuery(String query) throws WebApplicationException
    {
        ResultSet rs = null;
        if (m_database != null)
        {
            try 
            {
                Statement stmt = m_database.createStatement();
                rs = stmt.executeQuery(query);
            }
            catch (SQLException e)
            {
                // invalid query
                System.out.println(query);
                throw new WebApplicationException(Response.Status.BAD_REQUEST);
            }
        }        
        return rs;
    }

    /**
     * Attempts to close the database. 
     * @throws WebApplicationException with a response code of  500 Server error
     */
    static public void closeDatbase() throws WebApplicationException
    {
        try
        {
            m_database.close();
            pooledSource.close();
        }
        catch(SQLException e)
        {
            throw new WebApplicationException(Response.Status.INTERNAL_SERVER_ERROR);
        }
    }
}

我是在Eclipse中这样做的,我得到一个警告,
pooledSource.close()
已被弃用。我以前从未使用过池连接,我只是想确保我做的每件事都是正确的。是否有更好的方法关闭Oracle池资源

不推荐使用的方法意味着不应使用此方法。在将来的版本中,可以完全清除
close()
方法。我建议删除
pooledSource.close()

另外,我建议不要使用
连接
数据源
的静态实例,因为您需要一个请求时的连接,而不是在整个应用程序中保持它的活动状态。始终先关闭
结果集
,然后关闭
连接
通过在
最后
块中添加它们来保证
关闭

  • 必须关闭连接才能返回到池
  • 始终在最后一个块中关闭连接
  • 永远不要将连接引用作为类成员持有——这是一种容易出错和糟糕的设计。应尽可能晚地获得连接,并尽快释放。把这样的东西当作班级成员是没有意义的
  • 在使用它们的地方关闭连接。您的代码在这里再次容易出错。如果您忘记调用
    closeDatabase()
    ,您正在泄漏连接
  • 注意: 不要在此处混淆关闭
    连接
    和关闭
    连接池

    因为它是被请求的,所以这里有一些正确和良好的连接处理代码:

    public void doSomethingWithDb(Connection con, ...) {
        boolean release = (con == null);
    
        try {
            con = PersistenceUtils.getConnection(con); //static helper return a new conenction from pool when provided con==null otherwise simply returns the given con
    
            //do something
    
            if(release) {
                con.commit();
            }
        }
        catch(SQLException e) {
            //handle errors, i.e. calling con.rollback() but be sure to check for con!=null before. Again maybe null-safe static helper method here.
        }
        finally {
            if(release && con!=null){
                con.close();
            }
        }
    }
    
    我使用连接作为方法参数,以便能够在一个db事务中调用许多这样的方法。但您始终可以将
    null
    作为连接的第一个参数,并且该方法可以为您从池中获取连接

    当您在一个“DB方法”中调用另一个“DB方法”时,您只需提供与底层方法的连接,这样您就可以在一个事务中拥有所有内容

    正如您所看到的,正确的JDBC代码会产生很多样板代码。在第一步中,您可以通过实现PersistenceUtils之类的实用程序类来减少它,该类提供静态空安全方法,如commit(Connection)、rollback(Connection)、getConnection(Connection)、close(Connection)。。。
    这样,您就可以摆脱所有的空检查,也可以在其中包括日志记录或其他内容。

    因此,我不需要显式关闭池连接,它是为我处理的吗?我想可能是这样,但我想100%确定,这样我就不会放弃连接而不是关闭连接。你不需要关闭连接池。如果您从池中获得连接,
    连接
    属于池连接,因此关闭连接将返回池。感谢您的详细解释。我惊讶地看到此答案被接受。问题是如何正确关闭池连接。答案是不同的:答案是关于关闭连接池。顺便说一句:问题中池连接的关闭至少非常容易出错。我认为这是疏忽处理的。@Fatal,如果您看到这个问题,您将看到OP引用了
    close()
    方法的弃用。另外,普通连接和PooledConnection是两个完全不同的连接,而关闭pooled connections会将其自身返回到池中,关闭普通连接会关闭连接到RDBMS本身的每个实例。@connection对象上的Elite Guester调用close()。可能在垃圾收集时也会检查它是否返回到池中(我不知道),但因为尽快将其返回到池中很重要,所以您必须自己调用它。按照步骤2以正确的方式进行操作-始终在finally块中关闭此类资源。感谢您的帮助,我已经应用了您在此处提供的建议。