Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/powershell/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
Spring batch 单事务中的Spring批处理tasklet_Spring Batch - Fatal编程技术网

Spring batch 单事务中的Spring批处理tasklet

Spring batch 单事务中的Spring批处理tasklet,spring-batch,Spring Batch,我使用FlatFileItemReader创建了一个spring批处理作业,它从一个分隔文件中读取数据,然后使用JdbcBatchItemWriter写入DB。我的setp配置如下所示 <batch:step id="step1"> <batch:tasklet> <batch:chunk reader="fileReader" writer="dbWriter" commit-interva

我使用FlatFileItemReader创建了一个spring批处理作业,它从一个分隔文件中读取数据,然后使用JdbcBatchItemWriter写入DB。我的setp配置如下所示

<batch:step id="step1">
        <batch:tasklet>
            <batch:chunk reader="fileReader" 
                writer="dbWriter" commit-interval="100">
            </batch:chunk>
        </batch:tasklet>
</batch:step>

上面的配置是为每100行打开单独的事务,因此如果在完成tasklet(步骤1)之前发生故障,则我无法恢复以前提交的行。是否有办法在单个事务中运行整个tasklet


注意:我正在使用MapJobRepositoryFactoryBean作为作业存储库,不想在数据库中创建元表以重新启动。

在Spring batch中,一个作业一次只能有一个事务

请注意下图,我们可以看到事务在步骤开始时打开,并在步骤结束时提交

事实上,使用SpringBatch的一个主要优点是,作为开发人员,我们不必担心事务管理。即使出现故障,它也会自动回滚整个未提交的事务

(我上次使用Spring Batch已经有一段时间了,我希望我的理解仍然有效:p)不使用面向chuck的tasklet,只需创建一个简单的tasklet即可。默认情况下,简单的tasklet将在单个事务中运行。考虑到您已经构建了reader和writer,您可以编写一个tasklet,它模仿面向chuck的步骤所做的工作(只是向您展示想法的伪代码):

公共类ReaderWriterTasklet实现Tasklet{
私人项目阅读器;
私人项目作者;
//和相应的二传手
公共重复状态执行(STEP供款,
ChunkContext(上下文){
列表区块=新建LinkedList();
while(true){
T item=reader.read();
如果(项==null){
打破
}否则{
添加(项);
}
}
writer.write(块);
返回RepeatStatus.FINISHED;
}
}
(我相信您应该已经知道如何定义运行tasklet的步骤了,对吧?那么我将跳过该步骤)


另一个肮脏的方法是继续使用区块,并将提交间隔设置为
Integer.MAX\u VALUE
。通过这样做,面向块的步骤将不断从读取器获取项,直到它到达末尾,并在一个大块中写入写入器,这一切都发生在一个事务中。

当我们在project和@EnableBatchProcessing中使用spring批处理时,注释将为其默认表创建自己的事务。因此,如果您想在我们的应用程序表中执行任何插入、更新或删除操作。我们必须提到JpaTransactionManager,而不是默认的spring批处理事务。
public class ReaderWriterTasklet<T> implements Tasklet {
    private ItemReader<T> reader;
    private ItemWriter<T> writer;
    // and corresponding setters

    public RepeatStatus execute(StepContribution contribution,
                     ChunkContext chunkContext) {
        List<T> chunk = new LinkedList<T>();
        while (true) {
            T item = reader.read();
            if (item == null) {
                break;
            } else {
                chunk.add(item);
            }
        }
        writer.write(chunk);
        return RepeatStatus.FINISHED;
    }
}