Правильно ли я закрываю пул Oracle? - PullRequest
3 голосов
/ 08 июня 2011

Я пытаюсь использовать пул соединений для моего веб-приложения на Java. Я использую базу данных 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?

Ответы [ 2 ]

6 голосов
/ 08 июня 2011

Устаревший метод означает, что этот метод не должен использоваться.В будущих выпусках метод close() может быть полностью очищен.Я предлагаю удалить pooledSource.close().

Кроме того, я бы предложил не иметь статический экземпляр Connection и DataSource, так как вам требуется соединение по запросу и не поддерживать его во всем приложении.Всегда сначала закрывайте ResultSet, а затем Connection и гарантируйте закрытие, добавляя их в блок finally.

1 голос
/ 08 июня 2011
  1. Соединение должно быть закрыто, чтобы его можно было вернуть в пул.
  2. Всегда закрывать соединение в блоке finally.
  3. Никогда не хранить ссылки на соединения как члены класса - этоподвержен ошибкам и плохой дизайн.Соединения должны быть обнаружены как можно позже и освобождены как можно скорее.Не имеет смысла хранить что-то подобное в качестве члена класса.
  4. Закрывайте соединения там, где они используются.Ваш код снова подвержен ошибкам.Если вы забыли позвонить closeDatabase(), у вас утечка соединений.

Внимание: не путайте, закрывая connection и закрывая connection pool здесь.

Потому что это былозапросил вот какой-то код для правильной и правильной обработки соединения:

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();
        }
    }
}

Я использую Connection в качестве параметра метода, чтобы иметь возможность вызывать многие из таких методов в одной транзакции БД.Но вы всегда можете указать null в качестве первого аргумента для Connection, и метод получит для вас соединение из пула.

Когда вы вызываете другой «DB-Method» внутри «DB-Method», вы просто предоставляете свойподключение к базовому методу - таким образом, у вас есть все в одной транзакции.

Как видите, правильный код JDBC дает много стандартного кода.На первом шаге вы можете уменьшить его, реализовав Utility-Class, такой как PersistenceUtils, который предоставляет статические нулевые безопасные методы, такие как commit (Connection), rollback (Connection), getConnection (Connection), close (Connection) ... С этим вы получаетеизбавьтесь от всех нулевых проверок, и вы также можете включить ведение журнала или что-то еще.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...