Когда нужно закрыть Connection, Statement, PreparedStatement и ResultSet в JDBC
Несколько вопросов по кодированию JDBC:
- Для одного клиентского приложения нам нужен пул соединений?
- Это хорошая идея создать соединение в начале и сохранить его в живых, не закрывая его до выхода приложения? Почему?
- PreparedStatement связан с Connection, если мое соединение не закрывается после каждого запроса, почему бы не сохранить PreparedStatement в активном состоянии и повторно использовать его другими способами?
- Если мы создадим PreparedStatement для каждого запроса, знает ли он, что это тот же PreparedStaement и игнорирует ненужные действия после первого раза?
- PreparedStatement не создает один раз и повторно использует много раз инструкцию? если да, зачем каждый раз закрывать его?
Я знаю, что вызов функции close() освободит ресурс. Но если мы знаем, что мы будем использовать его позже, зачем его выпускать, а затем запросить позже?
Как о многоклиентском приложении? нам нужен пул соединений и поэтому нам нужно каждый раз создавать и закрывать Connection, Statement и PreparedStatement?
спасибо,
Ответы
Ответ 1
Лично я бы использовал пул, так как это позаботится обо всем управлении ресурсами для вас. Если ваши требования к подключению меняются, вы можете легко изменить конфигурацию пула. С пулом на месте вы можете открывать/закрывать соединения и готовить заявления в соответствии с наилучшей практикой и оставлять управление ресурсами пулом.
Как правило, при использовании пула:
- закрытие соединения фактически просто вернет его в пул
- акт подготовки инструкции будет либо извлекать предварительно подготовленный оператор из кэша операторов соединения, либо если он недоступен, создайте новый оператор и кешируйте его для последующего использования.
- Акт закрытия PreparedStatement фактически просто вернет его в кеш оператора приложений.
Кроме того - в зависимости от реализации пула - он может уведомить вас, когда есть утечки ресурсов, что упрощает идентификацию этих проблем в вашем коде.
Взгляните на источник примера реализации, например DBCP - довольно интересно посмотреть, как они работают.
Ответ 2
1. Даже если у вас есть один клиент, пул соединений может по-прежнему быть полезным. Подключение к базе данных может занять значительное время, поэтому очень часто это может замедлить работу приложения с медленными сетевыми запросами. Кроме того, как объясняет @teabot, пул может помочь определить, не закрыто ли какое-либо соединение.
2. Не рекомендуется открывать соединение и оставлять его открытым навсегда по двум причинам. Сначала соединение может погибнуть, если есть временное прерывание сети. Чем дольше он открыт, тем больше вероятность, что он будет мертв, когда потребуется. Во-вторых, неудавшаяся транзакция может оставить соединение в состоянии, не подходящем для продолжения работы. Лучше всего открыть несколько соединений, повторно использовать их в течение пяти или десяти минут, а затем переработать их.
3. В зависимости от базы данных и драйвера соединение может иметь готовый кэш инструкций. Даже при использовании другого соединения RDBMS обычно кэширует операторы, которые в точности совпадают, включая параметры. Поэтому SELECT * FROM table WHERE value =? поскольку подготовленный оператор будет кэшироваться через соединения, но если вы укажете значение параметра, например SELECT * FROM table WHERE value = 'your_data', то, вероятно, он не будет кешировать сервер.
4. Как объясняется в 3, зависит от реализации РСУБД, выполните контрольный тест.
5. Нет необходимости закрывать и готовить снова выражение, которое будет повторно использоваться с разными параметрами. Просто заново установите параметры и выполните.
Для нескольких клиентов база данных всегда будет иметь ограничение одновременного подключения, которое обычно не является большим числом. Если все клиенты проходят через webapp, то в качестве пула, такого как DBCP, все в порядке. Но, очевидно, нежелательно создавать пул для каждого клиента с постоянным открытием нескольких соединений.