no caso de usar PreparedStatement com uma única conexão comum sem nenhum pool, posso recriar uma instância para cada operação dml / sql mantendo o poder das instruções preparadas?
Quero dizer:
for (int i=0; i<1000; i++) {
PreparedStatement preparedStatement = connection.prepareStatement(sql);
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
preparedStatement.close();
}
ao invés de:
PreparedStatement preparedStatement = connection.prepareStatement(sql);
for (int i=0; i<1000; i++) {
preparedStatement.clearParameters();
preparedStatement.setObject(1, someValue);
preparedStatement.executeQuery();
}
preparedStatement.close();
minha pergunta surge pelo fato de que eu quero colocar este código em um ambiente multithread, você pode me dar alguns conselhos? obrigado
java
jdbc
prepared-statement
Pluma de aço
fonte
fonte
sql
não muda com no loop? se essa consulta não muda para cada iteração do loop, por que você está criando uma novaPreparedStatement
para cada iteração (no primeiro trecho de código)? Existe algum motivo para isso?Respostas:
A segunda maneira é um pouco mais eficiente, mas uma maneira muito melhor é executá-los em lotes:
No entanto, você depende da implementação do driver JDBC de quantos lotes pode executar de uma vez. Você pode, por exemplo, querer executá-los a cada 1000 lotes:
Quanto aos ambientes multithread, você não precisa se preocupar com isso se adquirir e fechar a conexão e a instrução no menor escopo possível dentro do mesmo bloco de método de acordo com o idioma JDBC normal usando a instrução try-with-resources conforme mostrado em trechos acima.
Se esses lotes forem transacionais, você gostaria de desligar o autocommit da conexão e apenas confirmar a transação quando todos os lotes forem concluídos. Caso contrário, pode resultar em um banco de dados sujo quando o primeiro grupo de lotes for bem-sucedido e o posterior não.
fonte
inside the same method block
- você quer dizer que cada thread terá sua própria pilha e essas conexões e instruções estão empilhadas de um lado e de outra fonte de dados para cada nova chamada de executeFunction (== cada thread) instância separada de conexão. Eu entendi bem? "O loop em seu código é apenas um exemplo simplificado demais, certo?
Seria melhor criar
PreparedStatement
apenas uma vez e reutilizá-lo continuamente no loop.Em situações onde isso não é possível (porque complicou muito o fluxo do programa), ainda é benéfico usar um
PreparedStatement
, mesmo se você usá-lo apenas uma vez, porque o lado do servidor do trabalho (analisar o SQL e armazenar em cache a execução plano), ainda será reduzido.Para resolver a situação em que você deseja reutilizar o lado Java
PreparedStatement
, alguns drivers JDBC (como o Oracle) têm um recurso de cache: Se você criar umPreparedStatement
para o mesmo SQL na mesma conexão, ele fornecerá o mesmo (em cache ) instância.Sobre multi-threading: Eu não acho que as conexões JDBC podem ser compartilhadas entre vários threads (ou seja, usadas simultaneamente por vários threads) de qualquer maneira. Cada thread deve obter sua própria conexão do pool, usá-la e devolvê-la ao pool novamente.
fonte