繁体   English   中英

如何在Spring Batch中引发自定义异常?

[英]How to throw custom exception in spring batch?

我遇到了一种情况,在这种情况下,我必须跟踪使用spring batch编写的批处理中各种条件下的各种异常。 例如:如果在读取数据库时不可用,则抛出某些类型的异常并发送邮件,说明数据库不可用并终止批处理。 如果表不可用,则抛出其他异常并发送邮件,说明表不可用并终止批处理。 如果数据不满足sql语句中指定的条件,则不要执行任何操作,因为这是正常的作业终止。 到目前为止,我所能实现的全部是使用StepExecutionListener,在其中可以查看批处理是否读取了任何记录或failException是什么,但不是按照我想要的方式。 任何帮助/建议都可以。

我的context.xml

<?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:batch="http://www.springframework.org/schema/batch" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-3.0.xsd
        http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-4.0.xsd">

    <import resource="classpath:context-datasource.xml" />

    <bean
        class="org.springframework.beans.factory.config.PropertyPlaceholderConfigurer">

        <property name="location">
            <value>springbatch.properties</value>
        </property>
    </bean>

    <bean id="validator"
        class="org.springframework.validation.beanvalidation.LocalValidatorFactoryBean" />

    <bean id="jobRepository"
        class="org.springframework.batch.core.repository.support.MapJobRepositoryFactoryBean" />

    <bean id="jobLauncher"
        class="org.springframework.batch.core.launch.support.SimpleJobLauncher">
        <property name="jobRepository" ref="jobRepository" />
    </bean>


    <!-- ItemReader which reads from database and returns the row mapped by 
        rowMapper -->
    <bean id="databaseItemReader"
        class="org.springframework.batch.item.database.JdbcCursorItemReader">

        <property name="dataSource" ref="dataSource" />

        <property name="sql" value="SELECT * FROM employee1" />

        <property name="rowMapper">
            <bean class="com.abc.springbatch.jdbc.EmployeeRowMapper" />
        </property>

    </bean>


    <!-- ItemWriter writes a line into output flat file -->
    <bean id="databaseItemWriter"
        class="org.springframework.batch.item.database.JdbcBatchItemWriter">

        <property name="dataSource" ref="dataSource" />

        <property name="sql">
            <value>
                <![CDATA[        
                    insert into actemployee(empId, firstName, lastName,additionalInfo) 
                    values (?, ?, ?, ?)
                ]]>
            </value>
        </property>

        <property name="itemPreparedStatementSetter">
            <bean class="com.abc.springbatch.jdbc.EmployeePreparedStatementSetter" />
        </property>

    </bean>


    <!-- Optional ItemProcessor to perform business logic/filtering on the input 
        records -->
    <bean id="itemProcessor" class="com.abc.springbatch.EmployeeItemProcessor">
        <property name="validator" ref="validator" />
    </bean>

    <!-- Step will need a transaction manager -->
    <bean id="transactionManager"
        class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />


    <bean id="recordSkipListener" class="com.abc.springbatch.RecordSkipListener" />

    <bean id="customItemReadListener" class="com.abc.springbatch.CustomItemReadListener" />

    <bean id="stepExecutionListener" class="com.abc.springbatch.BatchStepExecutionListner">
        <constructor-arg ref="mailSender" />
        <constructor-arg ref="preConfiguredMessage" />
    </bean>

    <!-- Actual Job -->
    <batch:job id="employeeToActiveEmployee">
        <batch:step id="step1">
            <batch:tasklet transaction-manager="transactionManager">
                <batch:chunk reader="databaseItemReader" writer="databaseItemWriter"
                    processor="itemProcessor" commit-interval="10" skip-limit="500" retry-limit="5">
                    <batch:listeners>
                        <batch:listener ref="customItemReadListener"/>
                    </batch:listeners>
                    <!-- Retry included here to retry for specified times in case the following exception occurs -->
                    <batch:retryable-exception-classes>
                        <batch:include
                            class="org.springframework.dao.DeadlockLoserDataAccessException" />
                    </batch:retryable-exception-classes>
                    <batch:skippable-exception-classes>
                        <batch:include class="javax.validation.ValidationException" />
                    </batch:skippable-exception-classes>
                </batch:chunk>

            </batch:tasklet>
            <batch:listeners>
                <batch:listener ref="recordSkipListener" />
                <batch:listener ref="stepExecutionListener" />
            </batch:listeners>
        </batch:step>
    </batch:job>




    <!-- Email API bean configuarion -->

    <bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
        <property name="host" value="${constant.order.mailHost.response}" />
        <property name="port" value="${constant.order.mailPort.response}" />
        <property name="username" value="${constant.order.mailUsername.response}" />
        <property name="password" value="XXXXXX" />
        <property name="javaMailProperties">
            <props>
                <prop key="mail.transport.protocol">smtp</prop>
                <prop key="mail.smtp.auth">false</prop>
                <prop key="mail.smtp.starttls.enable">true</prop>
                <prop key="mail.debug">true</prop>
            </props>
        </property>
    </bean>
    <bean id="preConfiguredMessage" class="org.springframework.mail.SimpleMailMessage">
        <property name="from" value="abc@xyz.com" />
        <property name="to" value="abc@xyz.com" />
        <property name="subject" value="Skipped Records" />
    </bean>


</beans>


<!-- Email API bean configuarion -->

<bean id="mailSender" class="org.springframework.mail.javamail.JavaMailSenderImpl">
    <property name="host" value="${constant.order.mailHost.response}" />
    <property name="port" value="${constant.order.mailPort.response}" />
    <property name="username" value="${constant.order.mailUsername.response}" />
    <property name="password" value="XXXXXX" />
    <property name="javaMailProperties">
        <props>
            <prop key="mail.transport.protocol">smtp</prop>
            <prop key="mail.smtp.auth">false</prop>
            <prop key="mail.smtp.starttls.enable">true</prop>
            <prop key="mail.debug">true</prop>
        </props>
    </property>
</bean>
<bean id="preConfiguredMessage" class="org.springframework.mail.SimpleMailMessage">
    <property name="from" value="abc@xyz.com" />
    <property name="to" value="abc@xyz.com" />
    <property name="subject" value="Skipped Records" />
</bean>

StepExecutionListener.java

public class BatchStepExecutionListner implements StepExecutionListener {

    private JavaMailSender mailSender;

    private SimpleMailMessage simpleMailMessage;

    public BatchStepExecutionListner(JavaMailSender mailSender, SimpleMailMessage preConfiguredMessage) {
        // TODO Auto-generated constructor stub
        this.mailSender = mailSender;
        this.simpleMailMessage = preConfiguredMessage;
    }

    @Override
    public void beforeStep(StepExecution stepExecution) {
        // TODO Auto-generated method stub

    }

    @Override
    public ExitStatus afterStep(StepExecution stepExecution) {
        // TODO Auto-generated method stub
        stepExecution.getReadCount();
        MimeMessage message = mailSender.createMimeMessage();
        try {
            MimeMessageHelper helper = new MimeMessageHelper(message, true);

            helper.setFrom(simpleMailMessage.getFrom());
            helper.setTo(simpleMailMessage.getTo());
            helper.setSubject(simpleMailMessage.getSubject());
            helper.setText("These are the skipped records");

            FileSystemResource file = new FileSystemResource("filename.txt");
            helper.addAttachment(file.getFilename(), file);

        } catch (MessagingException e) {
            throw new MailParseException(e);
        }
        //mailSender.send(message);

        return null;
    }

}

谢谢

如果数据库已关闭,则在初始化应用程序上下文时(在进入作业执行之前),您将无法创建数据源。 除此之外,您确实应该考虑限制在应用程序中捕获的“合理”范围。 通常(至少在我们的商店中)数据库故障,网络问题或删除的表将被视为“灾难性”故障,因此我们不必费心将它们捕获在应用程序代码中。

应该有其他工具来监视网络/系统/数据库的运行状况,并有适当的配置管理工具来确保您的数据库具有适当的DDL。 应用程序层中的任何进一步检查都是多余的。

ItemWriteListener具有onWriteError(),而ItemReadListener具有onReadError()方法。 这可用于处理不同的异常并采取措施。

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM