2010-05-31 9 views
6

Ho eseguito l'operazione utilizzando l'annotazione Spring @Scheduled, ma per qualche motivo è in esecuzione due volte. La mia versione di Spring Framework è 3.0.2.Spring @Scheduled esegue l'attività due volte quando si utilizzano le annotazioni

@Service 
public class ReportService { 

    @Scheduled(fixedDelay=1000 * 60 * 60* 24) 
    @Transactional 
    public void dailyReportTask() 
    { 
     ... code here ... 
    } 

} 

Ecco il mio XML:

<?xml version="1.0" encoding="UTF-8"?> 
<beans xmlns="http://www.springframework.org/schema/beans" 
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:task="http://www.springframework.org/schema/task" 
    xsi:schemaLocation="http://www.springframework.org/schema/beans 
http://www.springframework.org/schema/beans/spring-beans.xsd 
http://www.springframework.org/schema/task 
http://www.springframework.org/schema/task/spring-task-3.0.xsd"> 
    <task:scheduler id="taskScheduler" /> 
    <task:executor id="taskExecutor" pool-size="1" /> 
    <task:annotation-driven executor="taskExecutor" 
     scheduler="taskScheduler" /> 
</beans> 
+0

È possibile incollare parte del contesto applicativo pertinente o altra configurazione di questo tipo? C'è forse un'altra operazione pianificata che chiama questo? – jasonmp85

risposta

0

Dove stai di eseguirlo? Il tuo PC? Server singolo? 2 server di app con bilanciamento del carico?

Potrebbe essere in esecuzione su (a) il tuo PC e (b) il tuo server, quindi sembra che stia funzionando due volte, se capisci cosa intendo: è in esecuzione correttamente una volta, solo su due posizioni distinte.

+0

Appena in esecuzione sulla mia macchina di sviluppo ... ha solo una istanza in esecuzione ... Lo eseguo da eclissi ... – newbie

+0

È in esecuzione su un app server sulla tua macchina, ad es. Tomcat, JBoss, Glassfish, a cui distribuisci da Eclipse? Oppure funziona come app standalone? Eclipse potrebbe farti eseguire una seconda app mentre una prima è ancora in esecuzione. – Brian

+0

Il suo server tomcat 6 incorporato Eclipse. E so che ho solo un'istanza in esecuzione, l'ho controllata dal task manager. – newbie

1

Secondo questo post: http://www.vodori.com/blog/spring3scheduler.html

Primavera 3.0.0 uscita aveva un bug in cui applicazioni web con un programmatore di operazione sarebbe finire per l'esecuzione di metodi in programma due volte. Questo problema è stato risolto in Spring 3.0.1.

C'è stato un altro bug segnalato che colpisce versione/s: 3.0.2 https://jira.springsource.org/browse/SPR-7216

che dovrebbe essere risolto nella versione/s: 3.0.3.

+2

Ho avuto lo stesso problema e utilizzo Spring 3.1.1.Release – SiMet

-1

Una soluzione vorrei suggerire è quello di fare componente scat come questo

-In contesto applicativo

<context:component-scan base-package="com.abc.cde.dao" /> 

In yourservlet-servlet.xml

<!-- package that had all the @Controller classes --> 

ho questo modo il servlet viene caricato solo se il web.xml viene caricato simile può essere fatto per l'attività

5

sta accadendo a causa del contesto ascoltatore

sufficiente rimuovere

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

da web.xml dovrebbe funzionare.

+1

perché funziona due volte a Spring Scheduler? Inoltre rimuovo l'ascoltatore di contesto, non ha funzionato due volte. Ma voglio sapere la ragione. –

+0

è possibile rimuovere il mio 'ContextLoaderListener' da web.xml? per fare questo lavoro – shareef

1

Ho appena avuto questo problema di recente ed è stato causato dalla mia app distribuita due volte in Tomcat da Eclipse. Il problema era che avevo rinominato la mia applicazione in eclipse ma il "wb-module deploy-name" specificato nel file "org.eclipse.wst.common.component" .settings aveva ancora il vecchio nome.

Nel gestore tomcat, ho potuto vedere che avevo 2 app in esecuzione con nomi diversi.

+0

Ho avuto lo stesso problema perché avevo un collegamento simbolico ROOT alla mia cartella dell'app ed entrambi sono stati distribuiti. – Zipper

2

Ho avuto lo stesso problema e alla fine ho scoperto che il problema si stava verificando a causa della creazione dei bean nello root context e nello servlet context.

Così, per risolvere questo problema, è necessario separare la creazione dei fagioli nei contesti appropriati.

This answer spiega molto bene come questo e quello che era risolto il mio problema.

0

Controllare se una scheduler config manuale nei file di configurazione (tramite Java/XML). I'ved lo stesso problema, e scopro che il mio config stava caricando la mia classe di pianificazione due volte:

In Java:

package com.mywork.br.myschuedulerpackage; 
{...} 
@Configuration 
@EnableScheduling 
public class SchedulerConfiguration { 

    @Bean 
    public CTXDataImporterScheduler ctxDataImporterScheduler() { 
     return new CTXDataImporterScheduler(); 
    } 
} 

In applicationContext.xml XML:

<context:component-scan base-package="com.mywork.br.myschuedulerpackage" /> 

E nel mio class Scheduler, ho avuto i thats di annotazione @Component era fermo dalla scansione del componente e caricato una seconda volta causando i metodi @scheduler in corso di esecuzione due volte. Ho rimosso il config Java e quindi sta lavorando bene ora!

0

Per risolvere il doppio-lavoro del @Scheduled metodo basta cancellare ContextLoaderListener da voi web.xml (se si utilizza l'applicazione web.xml-based):

<listener> 
    <listener-class>org.springframework.web.context.ContextLoaderListener</listener-class> 
</listener> 

O se si utilizza WebApplicationInitializer basata su applicazione basta cancellare una stringa che aggiunge ContextLoaderListener:

package com.dropbox.shortener.config; 

import org.springframework.web.WebApplicationInitializer; 
import org.springframework.web.context.support.AnnotationConfigWebApplicationContext; 
import org.springframework.web.filter.CharacterEncodingFilter; 
import org.springframework.web.servlet.DispatcherServlet; 
import javax.servlet.FilterRegistration; 
import javax.servlet.ServletContext; 
import javax.servlet.ServletException; 
import javax.servlet.ServletRegistration; 

public class DropboxShortenerWebApplicationInitializer implements WebApplicationInitializer { 

    @Override 
    public void onStartup(ServletContext container) throws ServletException { 
     AnnotationConfigWebApplicationContext rootContext = new AnnotationConfigWebApplicationContext(); 
     rootContext.register(AppConfig.class); 

     // (!) Delete the next string 
     // container.addListener(new ContextLoaderListener(rootContext)); 

     AnnotationConfigWebApplicationContext dispatcherContext = new AnnotationConfigWebApplicationContext(); 
     dispatcherContext.register(WebConfig.class); 

     ServletRegistration.Dynamic dispatcher = container.addServlet("dispatcher", new DispatcherServlet(dispatcherContext)); 
     dispatcher.setLoadOnStartup(1); 
     dispatcher.addMapping("/"); 

     setupCharEncodingFilter(container); 
    } 

    private void setupCharEncodingFilter(ServletContext container) { 
     container.setInitParameter("defaultHtmlEscape", "true"); 

     FilterRegistration charEncodingFilterReg = container.addFilter("CharacterEncodingFilter", CharacterEncodingFilter.class); 
     charEncodingFilterReg.setInitParameter("encoding", "UTF-8"); 
     charEncodingFilterReg.setInitParameter("forceEncoding", "true"); 
     charEncodingFilterReg.addMappingForUrlPatterns(null, false, "/*"); 
    } 
} 
0

Usa @Scope (value = ConfigurableBeanFactory.SCOPE_ PROTOTIPO) sul tuo bean

0
Disabling below will work. 
<!-- <listener> 
    <listener-class> 
     org.springframework.web.context.ContextLoaderListener 
    </listener-class> 
</listener> --> 
Problemi correlati