E ai pessoal,
Recentemente estive procurando saber como otimizar alguns processos com multiplas interações usando o hibernate.
O cenário é de 4000 objetos a serem persistidos.
O script vigente é:
... /** controller ou main **/
try {
for (PrmParceiro prmP : prmParceiroS) {
if(prmP.getUsuario()==null){
prmP.setUsuario(usuario);
}
if (prmP.getId() == null){
dao.salvar(prmP);
}else{
dao.atualizar(prmP);
}
}
}catch (Exception e) {
System.out.println("Erro: "+e.getMessage());
tx.rollback();
}
...
// metodo salvar e atualizar da dao
...
tx = session.beginTransaction();
session.update(prmP); // ou session.save(prmP)
tx.commit();
...
Percebi que estava iniciando e encerrando a transação (begin, commit) a cada novo laço.
Além de criar vários objetos para transação, a própria transação é uma rotina que exige um x a mais de processamento do servidor sobre a base de dados.
Então criei uma aplicação para testar duas diferentes situações:
- salvar 4000 objetos com 4000 transações // modelo vigente.
- salvar 4000 objetos com 1 transação // nova tratativa
... /** controller ou main **/
try {
tx = session.beginTransaction();
for (PrmParceiro prmP : prmParceiroS) {
if(prmP.getUsuario()==null){
prmP.setUsuario(usuario);
}
if (prmP.getId() == null){
session.save(prmP);
}else{
session.update(prmP);
}
tx.commit();
}
}catch (Exception e) {
System.out.println("Erro: "+e.getMessage());
tx.rollback();
}
...
O correto é não deixar a transação na controller da aplicação, apenas para teste fiz desta forma.
O certo seria ter um método na dao que receba um arraylist para ser persistido ex: salvarParceiroS(ArrayList prmParceciroS) …
O resultado do teste:
A diferença foi de 01:39 mm:ss para 00:02 mm:ss. Em testes locais.
A primeira opção é 46 vezes mais demorada que a segunda.
A pergunta é: Existe alguma outra tratativa que otimize processos de persistencia em massa.
A aplicação de teste está disponível para baixar no endereço http://designcomd.com.br/documents/hibernate.rar
[]s
Jsign.