【问题标题】:Spring batch commit interval rollback issue for duplicate record in database数据库中重复记录的春季批量提交间隔回滚问题
【发布时间】:2017-09-08 08:48:01
【问题描述】:

我正在尝试从 CSV 文件中读取行并保存到数据库中。我使用MultiResourceItemReader 委托FlatFileItemReaderJdbcBatchItemWriter 进行读取/持久操作。我配置了commit-interval 50(例如)并跳过策略。 我正在使用 spring-batch-3.0.8oracle 数据库

为了简单理解,在CSV文件中,我有2行,commit-interval是2。

这里,ROLLNO-201 是 DB 中已经存在的记录。

观察:

1.如果第一行与数据库中存在的记录重复,第二行是新记录。我看到新记录被插入数据库,跳过第一行,因为它是重复的。[按预期工作正常]。

ROLLNO  NAME    CLASS   CITY

201    JOHN     4       MADISON

202    STEPHEN  5       MADISON

2.如果第一行是新记录,第二行是数据库中存在的记录的副本。我看到新记录没有插入数据库。[问题]。

ROLLNO  NAME    CLASS   CITY

202    STEPHEN  5       MADISON

201    JOHN     4       MADISON

我看到事务回滚是基于提交间隔的记录,而不是基于 chunkSize。如果 commit-interval 为 10,则第 10 条记录不应与要提交的事务重复。

谁能帮帮我,因为我在这里一无所知?

<bean id="jobRepository"    class="org.springframework.batch.core.repository.support.JobRepositoryFactoryBean">
    <property name="transactionManager" ref="transactionManager" />
    <property name="dataSource" ref="cisDataSource" />
    <property name="lobHandler" ref="lobHandler" />
    <property name="isolationLevelForCreate" value="ISOLATION_READ_COMMITTED" />
</bean>

<bean id="transactionManager"
    class="org.springframework.jdbc.datasource.DataSourceTransactionManager">
    <property name="dataSource" ref="cisDataSource" />
</bean>

<bean id="cisDataSource" class="org.apache.commons.dbcp.BasicDataSource">
    <property name="initialSize" value="1" />
    <property name="maxActive" value="${db.connection.pool.size}" />
    <property name="driverClassName" value="oracle.jdbc.driver.OracleDriver" />
    <property name="url" value="${cisdb.connection.string}" />
    <property name="username" value="${cisdb.username}" />
    <property name="password" value="${cisdb.password}" />
</bean>

<batch:job id="mdtJob1">
<batch:step id="mdtJob1Step1">
    <batch:tasklet ref="fileTransferToProcessingFolderTasklet" />
    <batch:next on="COMPLETED" to="mdtJob1Step2" />
</batch:step>
<batch:step id="mdtJob1Step2">
    <batch:tasklet>
        <batch:chunk reader="multiResourceReader" writer="naxAddressSqlItemWriter"
            commit-interval="5">
            <batch:skip-policy>
                <bean class="org.springframework.batch.core.step.skip.AlwaysSkipItemSkipPolicy" scope="step"/>
            </batch:skip-policy>
            <batch:retry-policy>
                <bean class="org.springframework.retry.policy.NeverRetryPolicy" scope="step"/>
            </batch:retry-policy>
        </batch:chunk>
        <batch:no-rollback-exception-classes>
            <batch:include class="java.sql.SQLException"/>
            <batch:include class="org.springframework.dao.DuplicateKeyException"/>
            <batch:include class="java.sql.SQLIntegrityConstraintViolationException"/>
        </batch:no-rollback-exception-classes>
    </batch:tasklet>
    <batch:next on="COMPLETED" to="mdtJob1Step3" />
</batch:step>
<batch:step id="mdtJob1Step3">
    <batch:tasklet ref="fileTransferToArchiveFolderTasklet" />
</batch:step>
</batch:job>

<bean id="multiResourceReader"
    class="org.springframework.batch.item.file.MultiResourceItemReader"
    scope="step">
    <property name="delegate" ref="flatFileItemReader" />
    <property name="resources" value="${batch.processing.files}" />
</bean>

<bean id="flatFileItemReader" class="org.springframework.batch.item.file.FlatFileItemReader">
    <property name="lineMapper">
<bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">
            <property name="lineTokenizer">
<bean
                    class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer">
                    <property name="names"
                        value="${csv.fields.in.order}" />
                </bean>
            </property>
            <property name="fieldSetMapper">
<bean               class="org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper">
                    <property name="prototypeBeanName" value="addressDto" />
                </bean>
            </property>
        </bean>
    </property>
</bean>

<bean id="naxAddressSqlItemWriter"
    class="org.springframework.batch.item.database.JdbcBatchItemWriter">
    <property name="dataSource" ref="cdmDataSource" />
    <property name="sql" value="${nax.address.insertion.query}" />
    <property name="itemSqlParameterSourceProvider">
<bean class="org.springframework.batch.item.database.BeanPropertyItemSqlParameterSourceProvider" />
    </property>
</bean>

【问题讨论】:

  • 您好,欢迎来到 StackOverflow。请参阅stackoverflow.com/help/how-to-ask,了解如何提出正确的问题并根据指南改进您的问题。现在一些代码会很好,这样我们就可以仔细研究问题及其根源。
  • @FabianSchöner 添加请求的代码以进行更好的分析。提前致谢。
  • commit-interval= 2 的块大小是多少?另外,显示一些你的配置和编写器代码。
  • 我们在应用程序中的提交间隔为 50。编写器代码在上述共享代码中可用。我用过 org.springframework.batch.item.database.JdbcBatchItemWriter。
  • 在您的数据源配置中,您可以尝试将defaultAutoCommit 设置为false 以查看您是否看到行为变化?

标签: java oracle spring-batch


【解决方案1】:

我希望您现在已经找到了解决方案。以防万一你还没有

这个解决方案对我有用。

如果您尝试让 commit-interval = 1,这将确保一次插入一行,并且重复的行不会有新的条目进入数据库。

例如: 块(1)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-06-14
    • 1970-01-01
    • 2012-02-01
    • 1970-01-01
    • 2016-05-23
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多