Erro ao executar job (quartz plugin)
05/08/2014 18:26
0
Pessoal,
Estou com dificuldade em resolver um problema aqui e gostaria da ajuda de vocês:
Tenho um job, criado com o quartz plugin, que realiza alguma verificações diariamente no sistema. Nessa verificação eu abro uma nova sessão (MinhaDomain.withNewSession{}) e executo meu código.
A 1° vez que o job é executado tudo ocorre bem, mas nas execuções seguinte sempre ocorre "Illegal attempt to associate a collection with two open sessions; nested exception is org.hibernate.HibernateException: Illegal attempt to associate a collection with two open sessions"
Tentei fechar a sessão usando "sessionFactory.currentSession.close()" mas não surtiu efeito.
Tags: quartz job session


0
Dyego, tem como mostrar o código fonte do seu job?

De cara, já te digo o que é: ou você está mantendo a sessão na instância do plugin (o ideal é que seja criada uma nova sessão a cada execução) ou está passando a sessão de uma thread para outra.


0
Olá Henrique, o job tem mais de 400 linhas, dei uma resumida nele aqui:

class DailyJob {
static triggers = {
cron name: "MyTrigger", cronExpression: "08 30 03 * * ?"
}
def execute() {
try{
def variavel1 = Variavel1.findAllByBolinha("bolinha", [fetch:[atributo:"eager"]])

variavel1 = variavel1.collate((int)((variavel1.size()+1)/2))

/* Cria uma tread para cada lista */
ExecutorService executor1 = Executors.newSingleThreadExecutor()
ExecutorService executor2 = Executors.newSingleThreadExecutor()

/* Dispara as treads */
executor1.execute {
analyzes(list1)
}
executor2.execute {
analyzes(list2)
}
}catch(RuntimeException e){
log.info(e.message)
}
}

private analyzes(List lista){
Domain.withNewSession{
for(item in lista){
try{
metodoA(item)

metodoB(item)

metodoC(item)
}catch(RuntimeException e){
/* trata a exception */
}
}
/* tentei fechar a sessão aqui com o "sessionFactory.currentSession.close()", mas não adiantou */
}
}

private boolean metodoA(Variavel1 v){
/* realizo verificações, chamo serviços externos ao job */
}

private boolean metodoB(Variavel1 v){
/* realizo verificações, chamo serviços externos ao job */
}

private boolean metodoC(Variavel1 v){
/* realizo verificações, chamo serviços externos ao job */
}
}

Obrigado pela atenção.
06/08/2014 12:27


0
Henrique, ocorreu um erro na hora que cliquei em "responder" no post acima:
06/08/2014 12:33


0
06/08/2014 12:37


0
EITAA!!
agora vai
06/08/2014 12:38


0
Dyego, valeu pelo feedback sobre o Grails Brasil.

Vou dar uma olhada para que não ocorra mais.

Analisando seu código fonte, é exatamente isto. Você tem dois ExecutorService, para os quais está passando a mesma sessão. Tem de ser uma thread por sessão, e não a mesma sessão para mais de uma thread, por isto você está co mestes problemas.


0
Bom,
Então eu deveria remover o "Domain.withNewSession{" que está aqui

private analyzes(List lista){
Domain.withNewSession{
for(item in lista){
try{
metodoA(item)
...

e colocar aqui?

/* Dispara as treads */
Domain.withNewSession{
executor1.execute {
analyzes(list1)
}
}
Domain.withNewSession{
executor2.execute {
analyzes(list2)
}
}
06/08/2014 14:38


0
Oi Dyego, também não.

O ideal é que cada thread crie sua própria sessão de forma individual. Passe algum parâmetro para a sua thread, e a partir desta parametrização ela mesma se preocupe com as sessões, etc.

Se for passar classes de domínio para serem processadas em outras threads, lembre-se sempre de executar o método detach para removê-la da sessão da thread anterior e attach para anexá-la à merge da thread atual.



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