2016-08-09 1 views
2

ich folgendes ItemReader haben:Kann Frühling Retry mit Spring Batch verwendet werden FlatFileItemReader

import org.springframework.batch.item.ExecutionContext; 
import org.springframework.batch.item.ItemStreamException; 
import org.springframework.batch.item.file.FlatFileItemReader; 
import org.springframework.batch.item.file.LineMapper; 
import org.springframework.beans.factory.annotation.Autowired; 
import org.springframework.core.io.FileSystemResource; 
import org.springframework.retry.annotation.Retryable; 
import org.springframework.stereotype.Service; 

@Service 
public class MyReader extends FlatFileItemReader<Holding> { 

    @Autowired 
    public MyReader(LineMapper<Holding> lineMapper, File loadFile) { 
     setResource(new FileSystemResource(loadFile)); 
     final int NUMBER_OF_HEADER_LINES = 1; 
     setLinesToSkip(NUMBER_OF_HEADER_LINES); 
     setLineMapper(lineMapper); 
    } 

    @Override 
    @Retryable(value=ItemStreamException.class, maxAttempts=5, [email protected](delay=1800000)) 
    public void open(ExecutionContext executionContext) throws ItemStreamException { 
       super.open(executionContext); 
    } 
} 

Die Datei lesen (das heißt loadFile) kann sein oder auch nicht verfügbar sein, wenn der Job ausgeführt wird. Wenn die Datei nicht verfügbar ist, möchte ich, dass der Reader ca. 30 Minuten lang nicht reagiert und dann erneut versucht, die Datei zu öffnen. Wenn nach fünf Versuchen die Datei nicht gefunden wird, kann sie wie üblich fehlschlagen, indem ItemStreamException geworfen wird.

Leider versucht der obige Code nicht, das Öffnen der Datei erneut zu versuchen. Es löst ItemStreamException beim ersten Aufruf zum Öffnen und nicht erneut versuchen, zu öffnen.

Kann jemand bitte erklären, wie man das macht? Hinweis: Ich habe @EnableRetry auf der SpringBootApplication Klasse.

Antwort

0

Der Wechsel von Spring Boot Version 1.3.1.RELEASE zu 1.4.0.RELEASE (und die entsprechenden auto-versionierten Abhängigkeiten wie spring-boot-starter-batch) löste das Problem. Retry funktioniert in 1.4.0.RELEASE wie im OP implementiert. Funktioniert nicht in 1.3.1.RELEASE. Hier ist die gradle-Datei, die jetzt verwendet wird:

buildscript { 
    ext { 
     // Previously using 1.3.1.RELEASE where retry functionality does not work 
     springBootVersion = '1.4.0.RELEASE' 
    } 
    repositories { 
     mavenCentral() 
     mavenLocal() 
    } 
    dependencies { 
     classpath("org.springframework.boot:spring-boot-gradle-plugin:${springBootVersion}") 
    } 
} 

apply plugin: 'java' 
apply plugin: 'eclipse' 
apply plugin: 'spring-boot' 

configurations { 
    provided 
} 

sourceSets { 
    main { 
     compileClasspath += configurations.provided 
    } 
} 

jar { 
    baseName = 'load' 
    version = '1.0' 
} 
sourceCompatibility = 1.8 
targetCompatibility = 1.8 

repositories { 
    mavenCentral() 
    mavenLocal() 
} 

dependencies { 
    compile('org.springframework.boot:spring-boot-starter-batch') 
    compile('org.springframework.boot:spring-boot-configuration-processor') 
    compile('org.springframework.boot:spring-boot-starter-data-jpa') 
    compile('org.springframework.boot:spring-boot-starter-mail') 
    compile('org.springframework.boot:spring-boot-starter-aop') 
    compile('org.projectlombok:lombok:1.16.6') 
    compile('org.hibernate:hibernate-validator:5.2.4.Final') 
    compile('org.quartz-scheduler:quartz:2.2.3') 
    runtime('javax.el:javax.el-api:2.2.4') 
    runtime('org.glassfish.web:javax.el:2.2.4') 
    runtime('net.sourceforge.jtds:jtds:1.3.1') 
    testCompile('org.springframework.boot:spring-boot-starter-test') 
    testCompile('org.springframework.batch:spring-batch-test') 
} 



eclipse { 
    classpath { 
     containers.remove('org.eclipse.jdt.launching.JRE_CONTAINER') 
     containers 'org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.8' 
    } 
} 

task wrapper(type: Wrapper) { 
    gradleVersion = '2.11' 
} 

Hinweis: Considered JobExecutionDecider mit Schritt wiederholen Sie die FlatFileItemReader verwenden. Die ItemStreamException bewirkt jedoch, dass der gesamte Job und die Anwendung beendet werden, ohne dass der Entscheider eine Ausführungsmöglichkeit erhält.

0

Dieser funktioniert. Ich habe ein paar kleine Änderungen vorgenommen, weil ich deine Klassen nicht kenne.

build.gradle

buildscript { 
    repositories { 
     mavenCentral() 
    } 
    dependencies { 
     classpath(
       "org.springframework.boot:spring-boot-gradle-plugin:1.4.0.RELEASE", 
     ) 
    } 
} 

apply plugin: 'java' 
apply plugin: 'spring-boot' 

tasks.withType(JavaCompile) { 
    sourceCompatibility = JavaVersion.VERSION_1_8 
    targetCompatibility = JavaVersion.VERSION_1_8 
} 

repositories { 
    mavenCentral() 
} 

springBoot { 
    mainClass = "test.MyReader" 
} 

dependencies { 
    compile(
      'org.springframework.boot:spring-boot-starter', 
      'org.springframework.boot:spring-boot-starter-aop', 
      'org.springframework.retry:spring-retry', 
    ) 
} 

MyApplication.java

@EnableRetry 
@SpringBootApplication 
public class MyApplication implements CommandLineRunner { 
    private final MyReader myReader; 

    @Autowired 
    public MyApplication(MyReader myReader) { 
     this.myReader = myReader; 
    } 

    public static void main(String[] args) { 
     SpringApplication.run(MyApplication.class, args); 
    } 

    @Override 
    public void run(String... args) throws Exception { 
     myReader.read(); 
    } 
} 

MyReader.java

@Service 
public class MyReader { 
    private static final String PATH = "a2"; 
    private final Logger logger = LoggerFactory.getLogger(MyReader.class); 

    public MyReader() { 

    } 

    @Retryable(value = IOException.class, maxAttempts = 5, backoff = @Backoff(delay = 5000)) 
    public void read() throws IOException { 
     final Resource resource = new FileSystemResource(PATH); 
     logger.info("\n\nRead attempt: {}\n", resource); 
     try (BufferedReader reader = new BufferedReader(new InputStreamReader(resource.getInputStream(), StandardCharsets.UTF_8))) { 
      final String content = reader.lines().collect(Collectors.joining(" ")); 
      logger.info("\n\nFile content: {}\n", content); 
     } 
    } 
} 

Wenn Sie exe Niedlich und Datei ist da, Sie sehen in Protokollen eine "Read Versuch" Nachricht und eine "Datei Inhalt" Nachricht. Ich habe sogar leere Zeilen hinzugefügt, so dass es jetzt schwer zu übersehen ist.

Wenn die Datei nicht existiert, sehen Sie fünf "Read Versuch" Nachrichten und dann Ausnahme ausgelöst.

Ich habe die Wiederholungszeit auf 5 Sekunden geändert. Wenn Sie schnell genug sind, können Sie ohne Datei beginnen und dann eine Datei dort einfügen und Sie werden sehen, dass es funktioniert. Sie sollten einige Leseversuche und schließlich den Dateiinhalt sehen.

Ich kann sehen, Sie kämpfen schon seit ein paar Tagen mit diesem Problem. Bitte stelle keine unnötigen Fragen, da sie der Community nicht helfen. Versuchen Sie für die zukünftige Referenz, bei Ihrer einzigen Frage zu bleiben und diese bei Bedarf zu ändern.

+0

Ich kann Spring Retry auch außerhalb von Spring Batch 'FlatFileItemReader' arbeiten lassen. Im OP frage ich, wie man das in FlatFileItemReader von Spring Batch umsetzen kann. – James

Verwandte Themen