当前位置: 首页 > 知识库问答 >
问题:

Spring批量读取csv,并使用跳过/异常策略将数据转储到表中

蓬祺
2023-03-14

我们正在使用Spring Batch从CSV文件中读取记录并插入到数据库表中。

数据源和事务管理器

<!-- connect to database -->
    <bean id="dataSource"
        class="org.springframework.jdbc.datasource.DriverManagerDataSource">
        <property name="driverClassName" value="oracle.jdbc.OracleDriver" />
        <property name="url" value="**********" />
        <property name="username" value="**********" />
        <property name="password" value="**********" />
    </bean>

    <bean id="transactionManagerTest"
        class="org.springframework.batch.support.transaction.ResourcelessTransactionManager" />

作业配置

<!-- stored job-meta in database -->
    <bean id="jobRepository"
        class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
        <property name="dataSource" ref="dataSource" />
        <property name="transactionManager" ref="transactionManagerTest"  />
        <property name="databaseType" value="Oracle" />
    </bean>


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

下面是Spring批处理作业配置

<batch:job id="reportJob">
        <batch:step id="step1" >
            <batch:tasklet transaction-manager="transactionManagerTest" >
                <batch:chunk reader="cvsFileItemReader" writer="mysqlItemWriter" commit-interval="5" skip-limit="1000" processor-transactional="true">

                    <!-- 
                     <batch:skip-policy>
                        <bean class="org.springframework.batch.core.step.skip.AlwaysSkipItemSkipPolicy" scope="step"/>
                    </batch:skip-policy> -->
                    <batch:skippable-exception-classes>
                        <batch:include class="java.lang.Exception" />
                    </batch:skippable-exception-classes>
                    <!-- <batch:retry-policy>
                        <bean class="org.springframework.retry.policy.NeverRetryPolicy" scope="step"/>
                    </batch:retry-policy> -->
                    <batch:listeners>
                         <batch:listener ref="itemWriterListner"/>
                    </batch:listeners>
                </batch:chunk>
            </batch:tasklet>
        </batch:step>
    </batch:job>

这里我们定义了批处理:skippable-outtion-class,如果任何记录插入语句失败,应该使用它来处理。

举个例子,我们在 csv 文件中有 10 条记录,我们正在逐条读取并在 5 上插入到卡盘中的数据库表中,但在两者之间,比如说第 4 条记录插入失败,它应该继续第 5 条记录,并且应该只跳过第 4 条记录。

但是对于 batch:skippable-exception-classes,如果第 4 条记录失败,它将再次从第 1 条记录继续。所以在数据库表中我们有 1-3 条记录 2 次(重复记录)

请建议,如果我缺少Spring批次的任何配置属性。

共有3个答案

杨选
2023-03-14

这是在写入阶段发生异常时的标准行为。< br >

项目(从1到5)逐个写入,但作为单个块提交,如果发生错误,SB无法检测应跳过哪个项目,因此,SB如何决定应跳过哪些项目

SB再次开始写入阶段,但逐个写入项目(如设置提交间隔="1")以检测坏项目并将其发送到SkipListener.skipInWrite(item,异常)

使用选择/更新策略而不是简单的插入来写。

胡浩瀚
2023-03-14

我认为,这项工作仍在进行中。请参阅此 JIRA 问题和此问题。它已经讨论了很长一段时间:Spring论坛帖子 1 和帖子 2。也许对两个JIRA问题进行一些额外的投票会使它们更加重要,更有可能被添加。

施英哲
2023-03-14

您配置事务管理器的方式有问题(未包含在上面的配置中)。虽然 bellabax 是正确的,因为当正在写入的项目引发异常时,整个块都会回滚,并且每个项目都会被单独处理/写入以确定块中的哪个项目导致了错误,但关键点似乎不适合你实际回滚。

UPDATEResourcelessTransactionManager不是真正的事务管理器,不适用于事务资源(如数据库)。用真正的事务管理器配置你的工作,你会没事的。

 类似资料:
  • 我有以下步骤在批处理工作。 当某个异常抛出时,我在parseStepSkipListener中捕捉他并登录数据库。 我期待以下行为: 作业已启动 执行前面的步骤 开始执行解析步骤 阅读项目 进程项 写 哦,异常。 捕获异常,登录数据库,转到下一个块(读取、处理、写入)。 作业已启动 执行前面的步骤 开始执行解析步骤 阅读项目 进程项 写 哦,异常。 进程项 写入项 哦,异常。 捕获异常,登录数据库

  • const SKIP_NONE = 0x00; // 不忽略任何单元格、行 const SKIP_EMPTY_ROW = 0x01; // 忽略空行 const SKIP_EMPTY_CELLS = 0x02; // 忽略空单元格(肉眼观察单元格内无数据,并不代表单元格未定义、未使用) const SKIP_EMPTY_VALUE = 0X100; // 忽略单元格空数据

  • 在我的spring boot应用程序中,我试图进行批插入以提高写入性能。问题是,我定期获得重复数据,对于这些数据,我的表上有一些唯一的约束。在进行串行插入时,我只捕获DataIntegrityException并忽略它们。但在执行批插入时,即使一次插入失败,也不会保存整个批。我希望hibernate仍然保存不会抛出错误的记录。我正在使用存储库。saveAll()用于插入,我的数据库是Mysql

  • 问题内容: 众所周知,由于连接错误问题,我们无法从elasticsearch中获取超过10000行的python行。我想要从我的弹性簇中获取两个小时的数据,并且每5分钟要进行10000次观测。 1.)有什么方法可以将elasticsearch中的数据直接转储到csv或计数超过10000的某些Nosql数据库中。 我用python编写代码。 我正在使用Elasticsearch版本5 问题答案: 尝

  • 本文向大家介绍如何读取CSV文件并将值存储到C#中的数组中?,包括了如何读取CSV文件并将值存储到C#中的数组中?的使用技巧和注意事项,需要的朋友参考一下 CSV文件是逗号分隔的文件,用于以有组织的方式存储数据。它通常以表格形式存储数据。大多数企业组织将其数据存储在CSV文件中。 CSV文件是逗号分隔的文件,用于以有组织的方式存储数据。它通常以表格形式存储数据。大多数企业组织将其数据存储在CSV文

  • 问题内容: 例如,我在工作中有3个步骤(类似于Step1): 即使在步骤1中出现异常后,如何继续执行步骤2和3?我的意思是用Java配置。 问题答案: 这是创建流时如何配置它的示例。这应该与直接通过作业生成器进行配置类似:

  • 请看下面这个数据文件的架构 > 问题1:我需要将第一列数据分成两列,这样整数数据应该在一列中,数组数据应该在另一列中。不确定如何在Spark/Scala中实现?任何关于这一点的指示都将是有帮助的。 当我试图将此数据文件写入csv文件时,我得到了以下错误

  • 我是编程界的新手。嗯,我正在尝试使用ApachePOI库读取excel文件(5行5列)。我实际上有两个相同问题的实现。在第一个代码片段中,我只是读取excel文件并将其打印到控制台中。 然而,现在我正试图将读取的excel数据保存到一个数组中。所以我想在动态获取excel行和列大小后设置数组大小。但令我惊讶的是,当我执行第二个代码段时,似乎“while(cellIterator.hasNext()