2

Can you please let me know which Transaction Manager should be used in Spring Batch Application in Production ? I am using Resourceless Transaction manager. Is it fine ? I am facing this issue when reading the data from External Oracle DB

[org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler] (pool-3130-thread-1) Unexpected error occurred in scheduled task.: org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLRecoverableException: Closed Connection

@Bean
    public ResourcelessTransactionManager resourcelessTransactionManager() {
        return new ResourcelessTransactionManager();
    }

    @Bean
    public MapJobRepositoryFactoryBean mapJobRepositoryFactory(
            ResourcelessTransactionManager txManager) throws Exception {

        //LOGGER.info("Inside mapJobRepositoryFactory method");
        MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(txManager);
        factory.setTransactionManager(txManager);
        factory.setIsolationLevelForCreate("ISOLATION_READ_UNCOMMITTED");
        factory.afterPropertiesSet();

        return factory;
    }

    @Bean
    public JobRepository jobRepository(
            MapJobRepositoryFactoryBean factory) throws Exception {

        //LOGGER.info("Inside jobRepository method");
        return factory.getObject();
    }

    @Bean
    public ThreadPoolTaskExecutor taskExecutor() {
        ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
        taskExecutor.setCorePoolSize(5);
        taskExecutor.setMaxPoolSize(10);
        taskExecutor.setQueueCapacity(30);
        return taskExecutor;
    }

    @Bean
    public JobLauncher jobLauncher(JobRepository jobRepository,ThreadPoolTaskExecutor taskExecutor) {

        //LOGGER.info("Inside jobLauncher method");
        SimpleJobLauncher launcher = new SimpleJobLauncher();
        launcher.setTaskExecutor(taskExecutor);
        launcher.setJobRepository(jobRepository);
        final SimpleAsyncTaskExecutor simpleAsyncTaskExecutor = new SimpleAsyncTaskExecutor();
        launcher.setTaskExecutor(simpleAsyncTaskExecutor);
        return launcher;
    }
Nithin
  • 371
  • 7
  • 29
  • Check https://stackoverflow.com/questions/35652942/spring-batch-how-to-prevent-batch-from-storing-transactions-in-db or https://stackoverflow.com/questions/39359840/spring-boot-batch-resourcelesstransactionmanager-datasourcepropertiesdatasource – Luca Basso Ricci Dec 29 '17 at 08:04
  • Hi, I checked the link which you shared but my issue is different. I am not sure if i have to use DataSourceTransactionManager or ResourcelessTransactionManager for my Spring batch application. Can you please advise ? – Nithin Dec 31 '17 at 07:23
  • so `txManager` that you are setting in repository configuration , is that a `ResourcelessTransactionManager` ? – Sabir Khan Jan 01 '18 at 05:54
  • Specify your business data source & destinations plus your job meta data source & destinations. Just saying **Oracle DB** is not enough information, please provide purpose. – Sabir Khan Jan 01 '18 at 06:10
  • Hi, It is a Spring boot with Spring batch application where I am connecting to an external Oracle DB to read data from it and write it to SQLServer which is destination. It was running fine for few days but after that it started throwing Unexpected error occurred in scheduled task.: org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLRecoverableException: Closed Connection. Can you please advise ? – Nithin Jan 01 '18 at 06:34
  • If it was running fine few days & you didn't do any code changes, I would doubt something on DB side or your connection pool opening & closing settings but hard to figure out with static code. – Sabir Khan Jan 01 '18 at 10:31
  • Hi, Thanks for update. I am suspecting either of two things might have happened . Something changed from the network side related to connection or Something is wrong with my Datasource Configuration or Transaction Manager which i am using ! Any advice ? – Nithin Jan 01 '18 at 12:06

1 Answers1

0

As you have said in your question that you are using Oracle DB so most likely you wouldn't need a ResourcelessTransactionManager.

What your current code is doing is storing job meta data into map based in memory structure and my guess is that you wouldn't be doing that in production and you would actually be storing job meta data in DB - for later analysis , restart-ability etc

In Spring Batch , there are two kinds of transactions - one for your business data and methods and second for job repository and lets say you want to read from a file , write to a file and wish to store job meta data into MapJobRepository then your code would work OK.

But the moment you define a DataSource , you can't use ResourcelessTransactionManager . In fact , with databases , you don't need to define any transaction manager on your own but Spring Batch chunk oriented processing will take care of itself and will store job meta data into database.

Sabir Khan
  • 9,826
  • 7
  • 45
  • 98
  • Hi, Thanks for the update. This link has details about my datasource configuration https://stackoverflow.com/questions/47989214/spring-batch-after-validating-connection-getting-closed-connection-issue-while – Nithin Jan 01 '18 at 06:26