Как все говорят, вам нужно использовать пул соединений. Зачем? Как дела? И т.д.
Что не так с вашим решением
Я знаю это, так как я тоже думал, что когда-то это была хорошая идея. Проблема двоякая:
- Все потоки (запросы сервлета обслуживаются по одному потоку на каждый) будут использовать одно и то же соединение. Поэтому запросы будут обрабатываться по одному. Это очень медленно, даже если вы просто сидите в одном браузере и опираетесь на клавишу F5. Попробуйте: это звучит высокоуровнево и абстрактно, но эмпирически и проверяемо.
- Если соединение разорвано по какой-либо причине, метод init больше не будет вызываться (поскольку сервлет не будет выведен из эксплуатации). Не пытайтесь решить эту проблему, поместив try-catch в doGet или doPost, потому что тогда вы окажетесь в аду (что-то вроде написания сервера приложений без запроса).
- Вопреки тому, что можно подумать, у вас не будет проблем с транзакциями, поскольку начало транзакции связано с потоком, а не только с соединением. Я могу ошибаться, но так как это в любом случае плохое решение, не переживайте.
Почему пул соединений
Пулы соединений дают вам массу преимуществ, но больше всего они решают проблемы
- Создание реального подключения к базе данных является дорогостоящим. Пул подключений всегда имеет несколько дополнительных подключений и дает вам одно из них.
- Если не удается установить соединение, пул соединений знает, как открыть новое
- Очень важно: каждый поток получает свое собственное соединение. Это означает, что многопоточность обрабатывается там, где она должна быть: на уровне БД. БД суперэффективны и могут с легкостью обрабатывать параллельные запросы.
- Другие вещи (например, централизованное расположение строк соединения JDBC и т. Д.), Но есть миллионы статей, книг и т. Д.
Когда устанавливать соединение
Где-то в стеке вызовов, инициированном в вашем сервисном делегате (doPost, doGet, doDisco и т. Д.), Вы должны установить соединение, а затем сделать правильные вещи и вернуть его в блоке finally. Я должен отметить, что главный архитектор C # однажды сказал, что вы должны использовать finally
блоков в 100 раз больше, чем catch
блоков. Истинные слова никогда не произносились ...
Какой пул соединений
Вы находитесь в сервлете, поэтому вы должны использовать пул соединений, предоставляемый контейнером. Ваш код JNDI будет полностью нормальным, за исключением того, как вы получаете соединение. Насколько я знаю, все контейнеры сервлетов имеют пулы соединений.
В некоторых комментариях к ответам выше предлагается использовать определенный API-интерфейс пула соединений. Ваша WAR должна быть переносимой и «просто развернутой». Я думаю, что это в основном неправильно. Если вы используете пул соединений, предоставленный вашим контейнером, ваше приложение будет развернуто в контейнерах, которые охватывают несколько компьютеров, и все эти интересные вещи, которые предоставляет спецификация Java EE. Да, дескрипторы развертывания для конкретного контейнера должны быть написаны, но это EE-способ, мон.
Один комментатор упоминает, что некоторые предоставленные контейнером пулы соединений не работают с драйверами JDBC (он упоминает Websphere). Это звучит совершенно надуманным и смешным, так что, вероятно, это правда. Когда происходят подобные вещи, выбрасывайте все, что вы «должны делать», в мусор и делайте все, что можете. Это то, за что нам иногда платят:)