【问题标题】:Why do I need an ItemReader in my job step if I only need to delete rows using ItemWriter如果我只需要使用 ItemWriter 删除行,为什么在我的工作步骤中需要一个 ItemReader
【发布时间】:2020-10-01 23:07:10
【问题描述】:

我的批处理作业中有一个步骤,我只想用来从表中删除行。

步骤如下:

@Bean 
    public Step step2(StepBuilderFactory factory,
                      PurgeAggBalanceWriter writer,
                      DataSource dataSource,
                      PlatformTransactionManager platformTransactionManager){
        return stepBuilderFactory.get("step2")
                .transactionManager(platformTransactionManager)
                .<Assessment,Assessment>chunk(10)
                .reader(getReader(dataSource, READER_QUERY2, "AggBalanceMapper", new AggBalanceMapper()))
                .writer(writer)
                .build();
    }

我正在使用这个带有 jdcb 模板的 writer 类来运行删除语句:

public class PurgeAggBalanceWriter implements ItemWriter<Assessment> {
   
    private JdbcTemplate jdbcTemplate;

    private static final String DELETE_QUERY = "DELETE FROM TABLE WHERE COLUMN = 'TEST'";

    public PurgeAggBalanceWriter(DataSource dataSource) {

        this.jdbcTemplate = new JdbcTemplate(dataSource);
    }


    @Override
    public void write(List<? extends Assessment> list) {

        jdbcTemplate.update(DELETE_QUERY);

}

该步骤成功完成,但我不明白为什么需要 ItemReader,因为当我尝试从步骤 2 中删除 .reader() 时它指出。

有没有办法避免使用读取器/映射器而只使用写入器,因为我所要做的就是运行删除查询?

【问题讨论】:

    标签: spring-batch


    【解决方案1】:

    我所要做的就是运行一个删除查询

    在这种情况下,您不需要面向块的 tasklet。一个简单的 tasklet 就足够了,比如:

    public class DeletionTasklet implements Tasklet {
    
        private static final String DELETE_QUERY = "DELETE FROM TABLE WHERE COLUMN = 'TEST'";
        private JdbcTemplate jdbcTemplate;
    
        public DeletionTasklet(DataSource dataSource) {
            this.jdbcTemplate = new JdbcTemplate(dataSource);
        }
    
        @Override
        public RepeatStatus execute(StepContribution contribution, ChunkContext chunkContext) {
            jdbcTemplate.update(DELETE_QUERY);
            return RepeatStatus.FINISHED;
        }
    }
    

    【讨论】:

    • 你好 Mahmoud,我在删除少量行时对此进行了测试,它似乎工作正常,尽管当我使用此解决方案删除大量行时,我得到一个 sql 回滚异常:*com. ibm.db2.jcc.am.SqlNonTransientConnectionException:[jcc][t4][10335][10366][4.14.113] 无效操作:连接已关闭。 ERRORCODE=-4470, SQLSTATE=08003 *
    • 似乎以某种方式陷入死锁状态......当我对少量行运行任务时,它工作正常,但最终需要删除数千行,这是我遇到这个问题...
    • 根据错误,您的查询运行时连接似乎已关闭。我不是 db2 专家,但您需要配置 db2 以允许长时间运行的查询。在 Spring Batch 方面,tasklet 将在事务中执行,您可以使用 step builder transactionAttribute() 方法(超时、隔离、传播等)配置该事务。
    • 无需重复类似的问题:stackoverflow.com/questions/64213585/…。将相关的东西放在同一个线程中会更有效率。
    • 是否建议分块处理数据以避免超时?
    猜你喜欢
    • 2019-06-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2020-05-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多