Создание пула соединений с базой данных - PullRequest
7 голосов
/ 10 ноября 2009

Нужна информация о создании пула соединений с базой данных (независимо от базы данных) и насколько они эффективны? В каких условиях они могут повысить производительность.

Как создать это явно?

Ответы [ 7 ]

6 голосов
/ 11 ноября 2009

Ваш вопрос немного двусмысленный:

Вы хотите homegrow реализацию пула соединений? Если это так, то это хорошая отправная точка: http://java.sun.com/developer/onlineTraining/Programming/JDCBook/conpool.html Но это крайне нежелательно для производственных сред. Лучше использовать существующий и тщательно протестированный API пула соединений, например DBCP или C3P0 .

Или вы хотите знать, как использовать пул соединений? Если это так, ответ зависит от используемого вами API пула соединений. К счастью, он обычно доступен на веб-сайте соответствующего API.

Или вы хотите узнать, когда / почему использовать пул соединений? Если это так, это, несомненно, повысит производительность соединения, если у вас есть долгоживущее приложение (например, веб-приложение), и вам нужно подключаться к базе данных чаще, чем часто. Обычная практика JDBC состоит в том, чтобы: и закрыть Connection, Statement и ResultSet в кратчайшем возможном объеме (то есть внутри того же самого блока метода). Поскольку подключение довольно дорого и может занять до 200 мс времени или даже больше, использование пула подключений намного быстрее. Он предоставляет соединения по требованию и заботится о фактическом закрытии соединения. Это, однако, не означает, что вы можете изменить способ написания JDBC, вам все равно нужно приобрести и закрыть их в кратчайшей возможной области. Единственное, что вам нужно изменить, - это способ подключения. Например. изменить с

connection = driverManager.getConnection();

до

connection = connectionPool.getConnection();

Больше никаких изменений не требуется, если ваш код JDBC хорошо написан.

3 голосов
/ 10 ноября 2009

Страница вступления к Apache DBCP хорошо подводит итог:

Создание нового соединения для каждого пользователь может занимать много времени (часто требуется несколько секунд часов время), чтобы выполнить базу данных транзакция, которая может занять миллисекунды. Открытие соединения по пользователь может быть невозможным в общедоступное интернет-приложение где количество одновременных пользователей может быть очень большим. Соответственно, разработчики часто хотят поделиться «пул» открытых связей между всеми из текущих пользователей приложения. Количество пользователей на самом деле выполнение запроса в любой момент времени как правило, очень маленький процент общее количество активных пользователей и во время обработки запроса является единственным время, когда соединение с базой данных требуется. Само приложение логи в СУБД, и обрабатывает любого пользователя внутренние проблемы с учетной записью.

Насколько они эффективны? Зависит от реализации. Обычно я ожидаю, что пул будет создавать экземпляры соединений при запуске или по запросу. Первое соединение потребует реального соединения с базой данных, и после этого, когда вы запрашиваете соединение, вы получаете существующее соединение в пуле. Таким образом, первый запрос на подключение займет больше времени, а затем вы просто извлекаете объекты из коллекции (очень быстро).

1 голос
/ 03 августа 2015

Создание пула соединений с базой данных с помощью tomcat

1. Tomcat введите ресурс внутри: conf / context.xml

Поместить записи ресурсов в файл context.xml:

<!-- jdbc/jndiName jndi --> 
<Resource name="jdbc/jndiName" auth="Container" type="javax.sql.DataSource" initialSize="1" maxActive="100" maxIdle="30" maxWait="10000" username="enter username" password="enter password" driverClassName="diver name" url="jdbc database url"/>

2. создать класс, который создаст пул соединений

public class MyConnectionFactory {
    private static String module = "[ QuoteConnectionFactory ]";
    private static QuoteConnectionFactory connectionFactory;

    protected QuoteConnectionFactory() {
    }

    /**
     *
     * @return=>getInstance() is a static method which will return the instance
     *                        of its own class
     */
    public static QuoteConnectionFactory getInstance() {
        if (connectionFactory == null)
            connectionFactory = new QuoteConnectionFactory();
        return connectionFactory;
    }

    /**
     *
     * @param jndiName

     */
    public Connection getConnection(String jndiName) {
        System.out.println("jndiName=======" + jndiName);
        Connection conn = null;
        InitialContext cxt = null;
        DataSource dataSource = null;
        try {
            cxt = new InitialContext();
            Context envContext  = (Context)cxt.lookup("java:/comp/env");
            dataSource = (DataSource)envContext.lookup(jndiName);
        } catch (NamingException e) {

        } catch (Exception e) {

        }

        if (dataSource == null) {

            try {
                conn = dataSource.getConnection();
            } catch (Exception e) {

            }

            System.out.println("connection===================" + conn);
            return conn;
        }
    }

3. редактировать файл web.xml

<resource-ref>
    <description>DB Connection</description>
    <res-ref-name>jdbc/jndiName</res-ref-name>
    <res-type>javax.sql.DataSource</res-type>
    <res-auth>Container</res-auth>
</resource-ref>

4. Используйте в коде

Connection con= QuoteConnectionFactory.getInstance(). getConnection("jndiName");
1 голос
/ 11 ноября 2009

Посмотрите на BoneCP (http://jolbox.com) в разделе тестов для некоторых чисел. Помните, что prepareStatements и т. Д. Привязаны к соединению, поэтому вам придется подготавливать их снова и снова, если вы имеете дело с соединениями Вы сами (пул подключений также кеширует их для вас).

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

1 голос
/ 10 ноября 2009

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

Более того, по крайней мере в Oracle вы сохраняете скомпилированный оператор связанным с соединением, поэтому повторное выполнение одного и того же оператора SQL еще быстрее.

(см. PreparedStatement, если вы находитесь в Java / JDBC)

Единственный риск снижения производительности - когда вы храните слишком много незанятых соединений в своем пуле, связанные ресурсы (ваша сторона и база данных) теряются.

1 голос
/ 10 ноября 2009

Создание соединений с базами данных - очень дорогие операции. Пулы соединений - это экземпляры соединений с базой данных, которые создаются и кэшируются. Каждый раз, когда требуется новое соединение с базой данных, вместо создания нового соединения используется одно из пула. Некоторые платформы, такие как .NET + SQL Server, по умолчанию используют пулы соединений (вам не нужно создавать свои собственные). Таким образом, они в основном повышают производительность, экономя время при создании новых соединений каждый раз.

0 голосов
/ 10 ноября 2009

Создание соединения с базой данных может быть, а может и не быть дорогостоящей операцией, в зависимости от вашей среды и того, что вы собираетесь с ней делать.

Если вы собираетесь выполнить один очень простой запрос, то подключение, вероятно, займет больше времени (или дольше), чем запрос.

Некоторые базы данных имеют гораздо большую нагрузку на соединение, чем другие; если настроено правильно, mysql должен иметь очень мало (выше времени, чтобы установить соединение TCP и выполнить рукопожатие протокола). Однако, если задержка для вашего сервера очень высока, даже это может быть весьма значительным (особенно если вы собираетесь выполнять только несколько запросов).

Если вы планируете выполнить, скажем, 100 запросов или несколько действительно медленных запросов, то время соединения исчезает до минимума.

В общем, я бы сказал, открывайте новое соединение каждый раз, пока вы не продемонстрируете, что это реальная проблема с производительностью. Использование пула соединений может привести к ошибкам, которые нам не нравятся:

  • Состояние соединения не было полностью сброшено после предыдущего использования в пуле - поэтому некоторое состояние задерживается и создает неожиданное поведение, приводящее к ошибке
  • Соединение каким-то образом было закрыто (возможно, из-за превышения времени ожидания межсетевого экрана), которое не может быть обнаружено, поэтому приложение пытается использовать закрытое соединение, вызывая длительную задержку или сбой
...