Как установить пул соединений в JDBC?

Кто-нибудь может предоставить примеры или ссылки о том, как установить пул соединений JDBC?

Из поиска в Google я вижу много разных способов сделать это, и это довольно запутанно.

В конечном итоге мне нужен код для возврата объекта java.sql.Connection, но у меня возникают проблемы с началом работы. , любые предложения приветствуются.

Обновление: Разве у javax.sql или java.sql нет реализаций пула соединений? Почему бы не использовать их лучше?

вопрос задан 14.05.2010
llm
2156 репутация

13 ответов


  • 96 рейтинг

    Если вам нужен автономный пул соединений, я предпочитаю C3P0 вместо DBCP (о котором я упоминал в предыдущем 385168709), у меня только что было слишком много проблем с DBCP при большой нагрузке. Использование C3P0 очень просто. Из документации :

    ComboPooledDataSource cpds = new ComboPooledDataSource();
    cpds.setDriverClass( "org.postgresql.Driver" ); //loads the jdbc driver
    cpds.setJdbcUrl( "jdbc:postgresql://localhost/testdb" );
    cpds.setUser("swaldman");
    cpds.setPassword("test-password");
    
    // the settings below are optional -- c3p0 can work with defaults
    cpds.setMinPoolSize(5);
    cpds.setAcquireIncrement(5);
    cpds.setMaxPoolSize(20);
    
    // The DataSource cpds is now a fully configured and usable pooled DataSource 
    

    Но если вы работаете на сервере приложений, я бы порекомендовал использовать встроенный пул соединений, который он предоставляет. В этом случае вам необходимо настроить его (см. Документацию вашего сервера приложений) и получить источник данных через JNDI:

    DataSource ds = (DataSource) new InitialContext().lookup("jdbc/myDS");
    
    ответ дан Pascal Thivent, с репутацией 471494, 14.05.2010
  • 18 рейтинг

    Обычно, если вам нужен пул соединений, вы пишете приложение, которое выполняется в некоторой управляемой среде, то есть вы работаете на сервере приложений. Если это так, убедитесь, что проверьте, какие средства пула соединений ваш сервер приложений предоставляет , прежде чем пытаться использовать другие варианты.

    Готовое решение будет наилучшим образом интегрировано с остальными средствами серверов приложений. Однако, если вы не работаете на сервере приложений, я бы порекомендовал компонент Apache Commons DBCP . Он широко используется и предоставляет все основные функциональные возможности пула, которые требуются большинству приложений.

    ответ дан Tendayi Mawushe, с репутацией 19868, 14.05.2010
  • 14 рейтинг

    Не изобретай велосипед.

    Попробуйте один из готовых сторонних компонентов:

    • Apache DBCP - это используется внутри Tomcat, и с уважением.
    • c3p0

    Apache DBCP поставляется с другим примером настройки пула javax. SQL. Источник данных . Вот один образец , который может помочь вам начать.

    ответ дан Alexander Pogrebnyak, с репутацией 37480, 14.05.2010
  • 14 рейтинг

    Я бы порекомендовал использовать библиотеку commons-dbcp . Есть множество примеров , перечисленных о том, как его использовать, вот ссылка на простой переход . Использование очень просто:

     BasicDataSource ds = new BasicDataSource();
     ds.setDriverClassName("oracle.jdbc.driver.OracleDriver")
     ds.setUsername("scott");
     ds.setPassword("tiger");
     ds.setUrl(connectURI);
     ...
     Connection conn = ds.getConnection();
    

    Вам необходимо создать источник данных только один раз, поэтому обязательно прочитайте документацию, если вы не знаете, как это сделать. Если вы не знаете, как правильно писать операторы JDBC, чтобы не пропускать ресурсы, вы также можете прочитать эту страницу Википедии .

    ответ дан Eric Hauser, с репутацией 4917, 14.05.2010
  • 14 рейтинг

    HikariCP

    Это современно, это быстро, это просто. Я использую это для каждого нового проекта. Я предпочитаю это больше, чем C3P0, не слишком хорошо знаю другие пулы.

    ответ дан tobijdc, с репутацией 765, 3.06.2015
  • 7 рейтинг

    На сервере приложений, который мы используем там, где я работаю (Oracle Application Server 10g, насколько я помню), пул обрабатывается сервером приложений. Мы получаем javax.sql.DataSource , используя поиск JNDI с javax.sql.InitialContext .

    это сделано что-то вроде этого

    try {     
       context = new InitialContext();
       jdbcURL = (DataSource) context.lookup("jdbc/CachedDS");
       System.out.println("Obtained Cached Data Source ");
    }
    catch(NamingException e)   
    {  
        System.err.println("Error looking up Data Source from Factory: "+e.getMessage());
    }
    

    (Мы не писали этот код, он скопирован из этой документации . )

    ответ дан Powerlord, с репутацией 72071, 14.05.2010
  • 4 рейтинг

    Как ответили другие, вы, вероятно, будете счастливы с Apache Dbcp или c3p0 . Оба популярны, и работают нормально.

    Относительно вашего сомнения

    Не поддерживает Javax. sql или java. sql есть реализации пула соединений? Зачем не лучше ли использовать их?

    Они не предоставляют реализации, а скорее интерфейсы и некоторые классы поддержки, только для программистов, которые реализуют сторонние библиотеки (пулы или драйверы). Обычно вы даже не смотрите на это. Ваш код должен работать с соединениями из вашего пула так же, как они были «простыми», прозрачным способом.

    ответ дан leonbloy, с репутацией 51422, 14.05.2010
  • 4 рейтинг

    Vibur DBCP - еще одна библиотека для этой цели. Несколько примеров, показывающих, как настроить его для использования с Hibernate, Spring + Hibernate или программно, можно найти на его веб-сайте: http: // www. vibur. org /

    Также см. Заявление об отказе от ответственности здесь .

    ответ дан Simeon Malchev, с репутацией 392, 11.02.2014
  • 4 рейтинг

    Бассейн

    • Механизм объединения - это способ создания объектов заранее. Когда класс загружен.
    • Улучшает приложение. performance [Используя одни и те же объекты для выполнения каких-либо действий с объектными данными] & amp; memory [выделение и отмена выделения многих объектов создает значительные накладные расходы на управление памятью].
    • Очистка объекта не требуется, так как мы используем один и тот же объект, что снижает нагрузку на сборщик мусора.

    «Пул [ Object пул , String пул постоянных, Thread пул, пул подключений]

    Строка Постоянный пул

    • Строковый пул литералов поддерживает только одну копию каждого отдельного строкового значения. который должен быть неизменным.
    • Когда вызывается метод intern, он проверяет доступность объекта с тем же содержимым в пуле, используя метод equals. «Если в пуле имеется String-copy, тогда возвращается ссылка. «В противном случае объект String добавляется в пул и возвращает ссылку.

    Пример: строка для проверки уникального объекта из пула.

    public class StringPoolTest {
        public static void main(String[] args) { // Integer.valueOf(), String.equals()
            String eol = System.getProperty("line.separator"); //java7 System.lineSeparator();
    
            String s1 = "Yash".intern();
            System.out.format("Val:%s Hash:%s SYS:%s "+eol, s1, s1.hashCode(), System.identityHashCode(s1));
            String s2 = "Yas"+"h".intern();
            System.out.format("Val:%s Hash:%s SYS:%s "+eol, s2, s2.hashCode(), System.identityHashCode(s2));
            String s3 = "Yas".intern()+"h".intern();
            System.out.format("Val:%s Hash:%s SYS:%s "+eol, s3, s3.hashCode(), System.identityHashCode(s3));
            String s4 = "Yas"+"h";
            System.out.format("Val:%s Hash:%s SYS:%s "+eol, s4, s4.hashCode(), System.identityHashCode(s4));
        }
    }
    

    Пул подключений с использованием Type-4 Драйвер с использованием сторонних библиотек [ DBCP2 , c3p0 , Tomcat JDBC 355 458 068 868 870 868 870 880 870 870 870 870 870 870 870 870 870 870 870

    Type 4 - The Thin driver converts JDBC calls directly into the vendor-specific database protocol Ex[Oracle - Thick, MySQL - Quora].

    wiki

    В механизме пула соединений, когда класс загружается, он получает объекты physical JDBC connection и предоставляет обернутый объект физического соединения пользователю. PoolableConnection - это обертка вокруг фактического соединения.

    • getConnection(), выберите одно из свободных упакованных соединений из соединения , пул объектов и верните его.
    • close() вместо закрытия возвращает упакованное соединение обратно в пул.

    Пример: использование ~ пула соединений DBCP2 с Java 7 [ try-with-resources ]

    public class ConnectionPool {
        static final BasicDataSource ds_dbcp2 = new BasicDataSource();
        static final ComboPooledDataSource ds_c3p0 = new ComboPooledDataSource();
        static final DataSource ds_JDBC = new DataSource();
    
        static Properties prop = new Properties();
        static {
            try {
                prop.load(ConnectionPool.class.getClassLoader().getResourceAsStream("connectionpool.properties"));
    
                ds_dbcp2.setDriverClassName( prop.getProperty("DriverClass") );
                ds_dbcp2.setUrl( prop.getProperty("URL") );
                ds_dbcp2.setUsername( prop.getProperty("UserName") );
                ds_dbcp2.setPassword( prop.getProperty("Password") );
                ds_dbcp2.setInitialSize( 5 );
    
                ds_c3p0.setDriverClass( prop.getProperty("DriverClass") );
                ds_c3p0.setJdbcUrl( prop.getProperty("URL") );
                ds_c3p0.setUser( prop.getProperty("UserName") );
                ds_c3p0.setPassword( prop.getProperty("Password") );
                ds_c3p0.setMinPoolSize(5);
                ds_c3p0.setAcquireIncrement(5);
                ds_c3p0.setMaxPoolSize(20);
    
                PoolProperties pool = new PoolProperties();
                pool.setUrl( prop.getProperty("URL") );
                pool.setDriverClassName( prop.getProperty("DriverClass") );
                pool.setUsername( prop.getProperty("UserName") );
                pool.setPassword( prop.getProperty("Password") );
                pool.setValidationQuery("SELECT 1");// SELECT 1(mysql) select 1 from dual(oracle)
    
                pool.setInitialSize(5);
                pool.setMaxActive(3);
                ds_JDBC.setPoolProperties( pool );
            } catch (IOException e) {   e.printStackTrace();
            } catch (PropertyVetoException e) { e.printStackTrace(); }
        }
    
        public static Connection getDBCP2Connection() throws SQLException {
            return ds_dbcp2.getConnection();
        }
    
        public static Connection getc3p0Connection() throws SQLException {
            return ds_c3p0.getConnection();
        }
    
        public static Connection getJDBCConnection() throws SQLException {
            return ds_JDBC.getConnection();
        }
    }
    public static boolean exists(String UserName, String Password ) throws SQLException {
        boolean exist = false;
        String SQL_EXIST = "SELECT * FROM users WHERE username=? AND password=?";
        try ( Connection connection = ConnectionPool.getDBCP2Connection();
              PreparedStatement pstmt = connection.prepareStatement(SQL_EXIST); ) {
            pstmt.setString(1, UserName );
            pstmt.setString(2, Password );
    
            try (ResultSet resultSet = pstmt.executeQuery()) {
                exist = resultSet.next(); // Note that you should not return a ResultSet here.
            }
        }
        System.out.println("User : "+exist);
        return exist;
    }
    

    jdbc::::: jdbc: oracle :thin:@localhost:1521:myDBName jdbc: mysql ://localhost:3306/myDBName

    пул соединений. свойства

    URL         : jdbc:mysql://localhost:3306/myDBName
    DriverClass : com.mysql.jdbc.Driver
    UserName    : root
    Password    :
    

    Web Приложение: Чтобы избежать проблемы соединения, когда все соединения закрыты [MySQL "wait_timeout" по умолчанию 8 часов] для того, чтобы заново открыть соединение с базовой БД.

    Вы можете сделать это для тестирования каждого соединения, установив testOnBorrow = true и validationQuery = "SELECT 1" и не использовать autoReconnect для сервера MySQL, поскольку оно устарело. выпуск

    ===== ===== context.xml ===== =====
    
    
    
        
    
    
    ===== ===== web.xml ===== =====
    
        DB Connection
        jdbc/MyAppDB
        javax.sql.DataSource
        Container
    
    ===== ===== DBOperations ===== =====
    servlet «   init() {}
    Normal call used by sevlet  « static {}
    
    static DataSource ds;
    static {
        try {
            Context ctx=new InitialContext();
            Context envContext = (Context)ctx.lookup("java:comp/env");
            ds  =   (DataSource) envContext.lookup("jdbc/MyAppDB");
        } catch (NamingException e) {   e.printStackTrace();    }
    }
    

    См. Также:

    ответ дан Yash, с репутацией 3756, 13.06.2016
  • 3 рейтинг

    Apache Commons имеет библиотеку для этой цели: DBCP . Если у вас нет странных требований в отношении ваших пулов, я бы использовал библиотеку, поскольку она должна быть хитрее и хитрее, чем вы могли бы надеяться.

    ответ дан sblundy, с репутацией 47873, 14.05.2010
  • 3 рейтинг

    В конце 2017 года Proxool, BoneCP, C3P0, DBCP в настоящее время больше не функционируют. HikariCP (созданный в 2012 году) кажется многообещающим, сносит двери всему, что я знаю. http: // www. baeldung. com / hikaricp

    Proxool имеет ряд проблем:
    - При большой нагрузке может превышать максимальное количество соединений и не возвращаться ниже максимального
    - Может не возвращаться к минимальным соединениям даже после истечения
    - Может заблокировать весь пул (и все потоки сервера / клиента), если у него есть проблемы с подключением к базе данных во время потока HouseKeeper (не использует. setQueryTimeout)
    - Поток HouseKeeper, имея блокировку пула соединений для своего процесса, запрашивает поток Prototyper для воссоздания соединений (очистки), что может привести к состоянию / блокировке гонки. В вызовах этих методов последний параметр всегда должен быть sweep: false во время цикла, только sweep: true под ним.
    - HouseKeeper нужен только один цикл PrototypeController в конце и имеет больше [упомянутых выше]
    - Поток HouseKeeper проверяет проверку соединений перед тем, как увидеть, какие соединения могут быть прерваны [некоторый риск проверки истекшего соединения, которое может быть разорвано / прервано из-за других тайм-аутов к БД в брандмауэре и т. Д. ]
    - В проекте есть незаконченный код (свойства, которые определены, но на которые не действовали)
    - Максимальное время жизни соединения по умолчанию, если оно не определено, составляет 4 часа (чрезмерно).
    - Поток HouseKeeper запускается каждые пять секунд для каждого пула (чрезмерно)

    Вы можете изменить код и внести эти улучшения. Но, поскольку он был создан в 2003 году и обновлен в 2008 году, ему не хватает почти 10 лет улучшений Java, которые используют такие решения, как hikaricp.

    ответ дан bluejaguar, с репутацией 31, 13.12.2017
  • 1 рейтинг

    Вы должны рассмотреть возможность использования UCP. Универсальный пул соединений (UCP) - это пул соединений Java. Это многофункциональный пул соединений, тесно интегрированный с базами данных Oracle Real Clusters (RAC), ADG, DG.

    См. Эту страницу для получения дополнительной информации о UCP.

    ответ дан Nirmala, с репутацией 614, 15.06.2016
  • 0 рейтинг

    MiniConnectionPoolManager - это реализация с одним Java-файлом, если вы ищете встраиваемое решение и не слишком беспокоитесь о производительности (хотя я не проверял его в этом отношении).

    Это мульти-лицензированный EPL , LGPL и MPL .

    В его документации также приведены альтернативы, достойные проверки (поверх DBCP и C3P0):

    ответ дан Matthieu, с репутацией 4448, 29.09.2015