Spring Batch - How to prevent batch from storing transactions in DB

生来就可爱ヽ(ⅴ<●) 提交于 2019-11-29 12:07:24

Add this beans to AppClass

@Bean
public PlatformTransactionManager transactionManager() {
    return new ResourcelessTransactionManager();
}


@Bean
public JobExplorer jobExplorer() throws Exception {
    MapJobExplorerFactoryBean jobExplorerFactory = new MapJobExplorerFactoryBean(mapJobRepositoryFactoryBean());
    jobExplorerFactory.afterPropertiesSet();
    return jobExplorerFactory.getObject();
}

@Bean
public MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean() {
    MapJobRepositoryFactoryBean mapJobRepositoryFactoryBean = new MapJobRepositoryFactoryBean();
    mapJobRepositoryFactoryBean.setTransactionManager(transactionManager());
    return mapJobRepositoryFactoryBean;
}

@Bean
public JobRepository jobRepository() throws Exception {
    return mapJobRepositoryFactoryBean().getObject();
}

@Bean
public JobLauncher jobLauncher() throws Exception {
    SimpleJobLauncher simpleJobLauncher = new SimpleJobLauncher();
    simpleJobLauncher.setJobRepository(jobRepository());
    return simpleJobLauncher;
}

This doesn't directly answer your question, but that is not a good solution; the map-based repository is supposed to be used only for testing. It will grow in memory indefinitely.

I suggest you use an embedded database like sqlite. The main problem in using a separate database for job metadata is that you should then coordinate the transactions between the two databases that you use (so that the state of metadata matches that of the data), but since it seems you're not even writing in the main database, that probably won't be a problem for you.

You could use an in-memory database (for example H2 or HSQL) quite easily. Examples of that you can find for example here: http://www.mkyong.com/spring/spring-embedded-database-examples/.

As for the Map-backed job repository, it does provide a method to clear its contents:

public void clear()

Convenience method to clear all the map DAOs globally, removing all entities.

Be aware that a Map-based job repository is not fit for use in partitioned steps and other multi-threading.

The following seems to have done the job for me:

@Bean
public DataSource dataSource() {        

    EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder();
    EmbeddedDatabase db = builder
        .setType(EmbeddedDatabaseType.HSQL) 
        .build();
    return db;
}

Now Spring is not creating tables in our production database, and when the JVM exits state is lost so nothing seems to be hanging around.

UPDATE: The above code has caused concurrency errors for us. We have addressed this by abandoning the EmbeddedDatabaseBuilder and declaring the HSQLDB this way instead:

@Bean
    public BasicDataSource dataSource() {
        BasicDataSource dataSource = new BasicDataSource();
          dataSource.setDriverClassName("org.hsqldb.jdbcDriver");
          dataSource.setUrl("jdbc:hsqldb:mem:testdb;sql.enforce_strict_size=true;hsqldb.tx=mvcc");
          dataSource.setUsername("sa");
          dataSource.setPassword("");
        return dataSource;
    }   

The primary difference is that we are able to specify mvcc (Multiversion concurrency control) in connection string which resolves the issue.

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!