в случае использования PreparedStatement с одним общим соединением без какого-либо пула, могу ли я воссоздать экземпляр для каждой операции dml / sql, сохраняя мощность подготовленных операторов?
Я имею в виду:
for (int i=0; i<1000; i++) {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
preparedStatement.close();
}
вместо того:
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i=0; i<1000; i++) {
preparedStatement.clearParameters();
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
}
preparedStatement.close();
Мой вопрос возникает из-за того, что я хочу поместить этот код в многопоточную среду, вы можете мне дать совет? Спасибо
java
jdbc
prepared-statement
Стальной шлейф
источник
источник
sql
не меняется в цикле? если этот запрос не меняется для каждой итерации цикла, то почему вы создаете новыйPreparedStatement
для каждой итерации (в первом фрагменте кода)? Есть ли причина для этого?Ответы:
Второй способ немного более эффективен, но гораздо лучше выполнять их партиями:
Однако вы зависите от реализации драйвера JDBC, сколько пакетов вы можете выполнить одновременно. Например, вы можете захотеть выполнять их каждые 1000 пакетов:
Что касается многопоточных сред, вам не нужно беспокоиться об этом, если вы приобретете и закроете соединение и оператор в кратчайшей возможной области внутри одного и того же блока метода в соответствии с обычной идиомой JDBC с использованием оператора try-with-resources, как показано на выше фрагменты.
Если эти пакеты являются транзакционными, то вы хотите отключить автоматическую фиксацию соединения и фиксировать транзакцию только после завершения всех пакетов. В противном случае это может привести к загрязнению базы данных, когда первая группа пакетов прошла успешно, а вторая - нет.
источник
inside the same method block
- вы имеете в виду, что каждый поток будет иметь свой собственный стек, и эти соединения и операторы находятся в стеке с одной стороны, а из другого источника данных будет давать каждому новому вызову executeFunction (== каждый поток) отдельный экземпляр соединения. Я вас правильно понял? »Цикл в вашем коде - это всего лишь чрезмерно упрощенный пример, верно?
Было бы лучше создать
PreparedStatement
только один раз и повторно использовать его снова и снова в цикле.В ситуациях, когда это невозможно (поскольку это слишком усложняет выполнение программы), по-прежнему полезно использовать a
PreparedStatement
, даже если вы используете его только один раз, потому что работа на стороне сервера (анализ SQL и кеширование выполнения план), все равно будет сокращаться.Чтобы решить ситуацию, когда вы хотите повторно использовать Java-сторону
PreparedStatement
, некоторые драйверы JDBC (например, Oracle) имеют функцию кэширования: если вы создадитеPreparedStatement
для того же SQL в том же соединении, он даст вам то же самое (кешированный ) пример.О многопоточности: я не думаю, что соединения JDBC могут быть разделены между несколькими потоками (т. Е. Могут использоваться одновременно несколькими потоками) в любом случае. Каждый поток должен получить собственное соединение из пула, использовать его и снова вернуть в пул.
источник