Amasta
Amasta

Reputation: 183

Spring Batch : How to change the default isolation level?

I read in the documentation :

"The default is ISOLATION_SERIALIZABLE, which prevents accidental concurrent execution of the SAME job"

However, when I launch DIFFERENT jobs at the the same time (with a default isolation level at SERIALIZABLE), I have the error : ORA-08177: can't serialize access for this transaction. Is it normal ?

Second, to change the Default Isolation Level to READ_COMMITTED, I understood that we can't change this level in application.properties, and, that I have to redefine BatchConfigurer. Exact ?

Using BasicBatchConfigurer, I must define an explicit contructor (implicit super constructor BasicBatchConfigurer() is undefined for default constructor). However, I have the error :

 Parameter 0 of constructor in MyBatchConfigurer required a bean of type 'org.springframework.boot.autoconfigure.batch.BatchProperties' that could not be found.

How to create : BatchProperties properties, DataSource dataSource and TransactionManagerCustomizers transactionManagerCustomizers ?

This is my code :

PeopleApplication.java

@SpringBootApplication
@EnableAutoConfiguration(exclude = { BatchAutoConfiguration.class })
public class PeopleApplication {
    
    
    public static void main(String[] args) throws Exception {
        
        ConfigurableApplicationContext ctx =  new SpringApplicationBuilder(PeopleApplication.class)
        .web(WebApplicationType.NONE) 
        .run(args);
        
        int exitValue = SpringApplication.exit(ctx);
        System.exit(exitValue);
    }
}

MyBatchConfigurer.java

@Component
@PropertySource("classpath:fileA.properties")
public class MyBatchConfigurer extends BasicBatchConfigurer implements CommandLineRunner, ExitCodeGenerator {

    protected MyBatchConfigurer(BatchProperties properties, DataSource dataSource, TransactionManagerCustomizers transactionManagerCustomizers) {
         super(properties, dataSource, transactionManagerCustomizers);
     }
     
     @Override
     protected String determineIsolationLevel() {
            return "ISOLATION_" + Isolation.READ_COMMITTED;
     }

    @Override
    public void run(String... args) {
        ...
    }

    ...
}

Regards.


RESPONSE :


use @EnableAutoConfiguration instead of :

@EnableAutoConfiguration(exclude = { BatchAutoConfiguration.class })

Like this, the bean BatchProperties, DataSource and TransactionManagerCustomizers will be automatically created.

Upvotes: 5

Views: 7162

Answers (1)

Rakesh
Rakesh

Reputation: 700

Please see the reply from Mahmoud that explains very clearly

can't serialize access for this transaction in spring batch.

Example for the usage is below and override only isolation level

--application.properties

spring.application.name=SpringBatch

####### SPRING ##############

spring.main.banner-mode=off
spring.main.web-application-type=none
spring.batch.initialize-schema=always
spring.batch.job.enabled=false // Disable default if you want to control

########JDBC Datasource########
#connection timeout 10 min
spring.datasource.hikari.connection-timeout=600000
spring.datasource.hikari.minimum-idle=5 
spring.datasource.hikari.maximum-pool-size=100
spring.datasource.hikari.idle-timeout=600000 
spring.datasource.hikari.max-lifetime=1800000 
spring.datasource.hikari.auto-commit=true 
spring.datasource.hikari.poolName=SpringBoot-HikariCP
spring.datasource.url=jdbc:oracle:thin:@ngecom.ae:1521:ngbilling
spring.datasource.username=ngbilling
springbatch.datasource.password=ngbilling

@SpringBootApplication
public class YourApplication {

    public static void main(String[] args) {
        SpringApplication.run(SsadapterApplication.class, args);
    }

}

// Your manual batch scheduler

 class BatchJobScheduler extends BasicBatchConfigurer {
        @Autowired
        private JobLauncher jobLauncher;
        @Autowired
        private ApplicationArguments args;
        @Autowired
        private Job myJob;
        protected BatchJobScheduler(BatchProperties properties, DataSource dataSource,
                TransactionManagerCustomizers transactionManagerCustomizers) {
            super(properties, dataSource, transactionManagerCustomizers);
        }
        @Override
        protected String determineIsolationLevel() {
            return "ISOLATION_" + Isolation.READ_COMMITTED;
        }
        //@Scheduled(cron = "${batch.cron}")
        public void notScheduledJob() {
                appId= args.getOptionValues("appId").get(0);
                JobParameters params = new JobParametersBuilder().addLong("jobId"+appId, System.currentTimeMillis())
                        .toJobParameters();
                jobLauncher.run(myJob, params);
        }
       

// Your batch Configuration And Spring will do everything for you to available

@Configuration
@EnableBatchProcessing
@EnableScheduling
public class BatchConfiguration {

    Logger logger = LoggerFactory.getLogger(BatchConfiguration.class);
    
  
    @Value("${batch.commit.chunk}")
    private Integer chunkSize;

    @Value("${batch.error.skipCount}")
    private Integer skipErrorCount;
    
    
    @Autowired
    private Environment environment;

    @Autowired
    public JobBuilderFactory jobBuilderFactory;

    @Autowired
    public StepBuilderFactory stepBuilderFactory;

    @Autowired
    private DataSource dataSource;

    @Autowired
    private ApplicationArguments args;
    
    @Autowired
    private JdbcTemplate jdbcTemplate; 

    @Bean
    public Job myJob() throws Exception {
        return jobBuilderFactory.get("myJob").incrementer(new RunIdIncrementer())
                .listener(new JobListener()).start(myStep()).build();
    } 

   @Bean
    public Step myStep() throws Exception {
        return stepBuilderFactory.get("myStep").<InputObject, OutPutObject>chunk(chunkSize)
                .reader(yourReader(null)).processor(yourProcessor()).writer(yourWriter())
                //.faultTolerant()
                //.skipLimit(skipErrorCount).skip(Exception.class)//.noSkip(FileNotFoundException.class)
                .listener(invoiceSkipListener())
                //.noRetry(Exception.class)
                //.noRollback(Exception.class)
                .build();
    }

Upvotes: 2

Related Questions