Importação de Dados
30/09/2014 17:03
1
Tenho que fazer uma sincronia de produtos de uma base firebird para o meu sistema, o serviço abaixo está realizando o procedimento. Porém quando tenho muitos produtos para sincronizar a importação começa ficar muito lenta. Existe alguma macete ou boa pratica que devo aplicar ao meu código para melhoria de performance? Segue o código abaixo:

class IntegradorRLIndService {
def importarProduto() {
println("IntegradorService - importarProduto")
Produto.withTransaction({ status ->
Sql sql = Utils.dataSourceImportacao() // Pega a URL de conexão do BD que vou importar os dados
StringBuilder qry = new StringBuilder()
qry.append("SELECT PRO_CODIGO\n")
// Todos os campos da tabela aqui <---
qry.append("FROM PRODUTO P\n")
sql.eachRow(qry.toString(), { row ->
println("row: $row")
def produto = Produto.findOrCreateWhere(proCodigoInd: row.pro_codigo)
produto.descricao = row.pro_descricao
produto.observacao = row.observacao
// Aqui passo os vários campos aqui <---
// E finalmente salvo o produto
if (!produto.save(flush: true, failOnError: true)) {
status.setRollbackOnly()
}
});
sql.connection.close()
})
}
}
Tags: migração sincronia sql domain class firebird


1
Castiel,

quando a importação é muito grande, e você pode fazê-la em pedaços, uma boa solução é fazê-lo em lotes. Ao invés de buscar tudo de uma vez, faça de N em N itens.

Assim você evita a sobrecarga do seu sistema. O que ocorre: quando você está executando o save, está muitas vezes acumulando os comandos que deverão ser enviados para o BD no momento de flush. Como isto é acumulativo e não tem limites, muito provavelmente é um dos fatores que pode estar consumindo seus recursos computacionais.

Outra alternativa arquitetural (e a minha favorita inclusive) é ter um sistema separado apenas para este tipo de integração. Assim você evita que a aplicação principal sofra no momento de importação, melhorando a experiência final do seu usuário.

Se for adotar uma estratégia como esta, minha sugestão é você dar uma estudada no Apache Camel: é um framework de integração excelente e que cai muito bem para este tipo de situação.


1
Fiz algumas alterações no meu código e ele melhorou a velocidade. O que estava "pesando" eram outras consultas que eram executadas durante o processo de importação. Por exemplo toda vez que passava por um item do meu select tinha que buscar grupo, subgrupo, ncm e etc daquele produto, então criei objetos para armazenar esses resultados, caso as consultas forem a mesma do registro anterior eu economizo consultas a minha base de dados.

Outra situação que fiz foi "paginar" a minha importação como o Kico havia indicado, agora vou importando de 30 em 30 registros para não sobrecarregar a importação.

Desconhecia sobre o Apache Camel, vou estuda-lo e ver se é uma opção viável para a minha situação.

Resumindo o que notei foi que várias consultas que estava executando sobrecarregava a importação, então tentei minimizar ao máximo as consultas ao banco.
01/10/2014 16:55


0
Oi Castiel, boa idéia: você aplicou o conceito de programação dinâmica. Não havia reparado isto no seu código.

Dê uma estudada nesta possibilidade que te passei de executar a importação assíncronamente em um processo independente. Normalmente vale demais à pena. :)



Ainda não faz parte da comunidade???

Para se registrar, clique aqui.


Aprenda Groovy e Grails com a Formação itexto!

Newsletter Semana Groovy

Assinar

Envie seu link!


Livro de Grails


/dev/All

Os melhores blogs de TI (e em português) em um único lugar!

 
Creative Commons
RSS Grails Brasil é mantido por itexto Consultoria.
Em caso de problemas contacte Henrique Lobo Weissmann (Kico) por e-mail: kico@itexto.com.br
Todo o conteúdo presente neste site adota o Creative Commons como licença padrão.
Ver: 4.14.0
itexto