Стратегия распределения доступа к Oracle JDBC Pool Connection? - PullRequest
3 голосов
/ 21 января 2012

При использовании пула соединений Oracle JDBC, есть ли способ контролировать, как раздаются соединения? В частности, есть ли способ указать, используя стратегию LIFO? Похоже, что соединения могут быть разосланы круглым способом.

В этом сценарии:

  • используется максимальное количество подключений в пуле (10)
  • после этого используется только одно параллельное соединение, каждые 5 секунд извлекается и возвращается
  • Тайм-аут неактивности установлен на 60 секунд

Если используется стратегия циклического перебора, каждое из 10 объединенных соединений будет использовано в течение 60 секунд. Когда происходит проверка таймаута неактивности, каждое соединение будет активным в течение последней минуты, поэтому ни одно соединение не будет кандидатом на закрытие. Пул соединений останется с 10 соединениями, хотя в действительности требуется только 1. По крайней мере, это то, что я, кажется, испытываю. Я бы хотел, чтобы пул сократился до 1 соединения.

Правильно ли я понимаю, как работает драйвер? Есть ли способ управления стратегией распределения соединений из пула (LIFO, FIFO, циклический перебор) или мне придется использовать другие механизмы объединения?

Ниже приведен тест (с использованием устаревшего API). В этом случае было создано 3 соединения, и оно уменьшилось бы до 2, а не 1.

РЕДАКТИРОВАТЬ, чтобы более точно отразить приведенное выше описание:

import java.io.IOException;
import java.sql.Connection;
import java.sql.SQLException;
import java.util.ArrayList;
import oracle.jdbc.pool.OracleDataSource;


public class Main {

    public static void main(String[] args) throws InterruptedException, IOException, ClassNotFoundException, SQLException {

        String url = "jdbc:oracle:thin:@//host:1521/SID";
        String user = "user";
        String pwd = "pwd";

        OracleDataSource ocpds;

        ArrayList<Connection> tempConnList = new ArrayList<>();


        try {

            ocpds = new OracleDataSource();
            ocpds.setURL(url);
            ocpds.setUser(user);
            ocpds.setPassword(pwd);

            java.util.Properties prop = new java.util.Properties();
            prop.setProperty("MinLimit", "1");
            prop.setProperty("MaxLimit", "10");

            prop.setProperty("InactivityTimeout", "60");    //  seconds
            prop.setProperty("AbandonedConnectionTimeout", "60");  //  seconds
            prop.setProperty("PropertyCheckInterval", "60"); // seconds            

            // set DataSource properties
            ocpds.setConnectionCachingEnabled(true);
            ocpds.setConnectionCacheProperties(prop);
            ocpds.setConnectionCacheName("TestCache");


            // Ramp up to max
            for (int i=0; i<10; i++) {
                Connection conn = ocpds.getConnection();
                tempConnList.add(conn);
            }

            // Release them all
            for (Connection conn : tempConnList) {
                conn.close();
            }


            // Grab and release one connection at a time
            for (int i = 0; i < 60; i++) {

                System.out.println(new java.util.Date());

                // Grab and release
                Connection conn = ocpds.getConnection();
                conn.close();

                try {
                    Thread.currentThread().sleep(5000);
                } catch (InterruptedException ie) {
                    System.err.println("error message: " + ie.getMessage());
                }

            }

        } catch (SQLException e) {
            System.err.println("error message: " + e.getMessage());
        } finally {
            for (Connection conn : tempConnList) {
                if (conn != null) { try { conn.close(); } catch (SQLException ignored) {}; }
            }
        }
    }

}

1 Ответ

2 голосов
/ 26 января 2012

Служба поддержки Oracle ответила, что для возврата соединений из пула используется метод циклического перебора.В Oracle JDBC 12 (текущая версия 11.2.0.3) будет свойство «UseLIFO», которое позволит извлекать «последний пришел первым»:

prop.setProperty("UseLIFO", "true");

В примере, опубликованном в вопросе, это позволит времени простоя сократить пул до одного соединения.

...