Spring Batch Intro SC Guide - දත්ත සැකසීම පහසුවෙන්

Spring Batch Introduction: විශාල දත්ත කන්දරාවක් ගොඩ දාමු!
කොහොමද යාලුවනේ!? අද අපි කතා කරන්න යන්නේ Spring Framework එකේ තියෙන, data processing වලදී අපිට නැතුවම බැරි module එකක් ගැන – ඒ තමයි Spring Batch. මේක ගැන ඔයාලා අහලා ඇති, සමහරවිට පාවිච්චි කරලත් ඇති. හැබැයි අද අපි බලමු මේක හරියටම මොකක්ද, මොකටද මේක පාවිච්චි කරන්නේ, ඒ වගේම පොඩි practical example එකකුත් කරලා බලමු.
අපි හැමෝම දන්නවා, software applications වලදී දත්ත කියන්නේ කොච්චර වැදගත්ද කියලා. සමහර වෙලාවට මේ දත්ත ගොඩක් විශාල වෙන්න පුළුවන් – ලක්ෂ ගණනින්, කෝටි ගණනින් records තියෙන්න පුළුවන්. බැංකු වල daily reports generate කරනවා, e-commerce sites වල orders process කරනවා, data analytics platforms වල terabytes of data analyze කරනවා. මේ වගේ scenarios වලදී, සාමාන්ය විදිහට එකවරටම ඔක්කොම data ටික memory එකට load කරලා process කරන්න ගියොත් වැඩේ එච්චර සාර්ථක වෙන්නේ නෑ. Memory out වෙන්න පුළුවන්, performance අවුල් වෙන්න පුළුවන්, එහෙමත් නැත්නම් පොඩි error එකකදී මුළු process එකම crash වෙන්න පුළුවන්.
මෙන්න මේ වගේ වෙලාවට තමයි Spring Batch කියන සුපිරි විසඳුම අපේ පිහිටට එන්නේ! මේක design කරලම තියෙන්නේ robust, high-volume batch processing jobs හදන්න. ඒ කියන්නේ දත්ත කන්දරාවක් වුණත් අලියා වගේ පොඩි කෑලි වලට කඩලා, එකින් එක process කරලා, ඒ අතරතුර මොනවා හරි අවුලක් ආවොත් එතනින්ම ආයෙත් පටන් ගන්න පුළුවන් විදිහට මේක හදලා තියෙනවා. අපි මේ ගැන ගැඹුරින්ම ඉගෙන ගමු.
Spring Batch කියන්නේ මොකක්ද? (What is Spring Batch?)
සරලවම කිව්වොත්, Spring Batch කියන්නේ enterprise-level batch applications develop කරන්න අවශ්ය features set එකක් සපයන lightweight, comprehensive framework එකක්. මේකෙන් කරන්නේ, data intensive operations වලදී, දත්ත කන්දරාවක් විශ්වාසදායක විදිහට process කරන්න අවශ්ය tooling ටික දෙක අතටම දෙන එක.
මේක මොකටද සාමාන්ය for loop එකකට වඩා වෙනස් වෙන්නේ? හිතන්න ඔයා ලක්ෂ 10ක Customer records තියෙන CSV file එකක් කියවලා, ඒකේ තියෙන email addresses validate කරලා, ඒවා database එකකට දාන්න ඕනේ කියලා. සාමාන්ය for loop එකකින් මේක කරන්න පුළුවන් තමයි, හැබැයි:
- Failure handling: Records 50,000ක් process කරද්දි application එක crash වුණොත්, ආයෙත් මුල ඉඳලම පටන් ගන්න වෙනවා. Spring Batch වලදී, ඒක restart කරන්න පුළුවන්.
- Resource Management: දත්ත කන්දරාවක් memory එකට load කරගන්නේ නැතුව, chunk by chunk process කරන්න පුළුවන්.
- Monitoring: Job එකේ progress එක, successful records ගාන, failed records ගාන වගේ දේවල් monitor කරන්න පුළුවන්.
- Transaction Management: එක් එක් chunk එක transaction එකක් ඇතුළත process කරන්න පුළුවන්.
- Scalability: Parallel processing, partitioning වගේ දේවල් support කරනවා.
මෙන්න මේ වගේ වාසි ගොඩක් Spring Batch එක්ක අපිට ලැබෙනවා. ඒ නිසා තමයි production environments වල විශාල data processing jobs වලට මේක ප්රබල විසඳුමක් වෙන්නේ.
Spring Batch Architecture එක (The Spring Batch Architecture)
Spring Batch වල core concepts කිහිපයක් තියෙනවා. මේවා තේරුම් ගත්තොත් අපිට වැඩේ ලේසි වෙනවා:
- Job: මේක තමයි මුළු batch process එකම නියෝජනය කරන්නේ. එක Job එකකට Steps එකක් හෝ කිහිපයක් තියෙන්න පුළුවන්. උදාහරණයක් විදිහට, "Daily Customer Data Processing Job" කියන්නේ Job එකක් වෙන්න පුළුවන්.
- Step: Job එකක තියෙන independently executable phase එකක් තමයි Step එකක් කියන්නේ. එක Step එකක් ඇතුළත data read කරනවා, process කරනවා, write කරනවා. උදාහරණයක් විදිහට, "Read CSV Step" එකක්, "Process Data Step" එකක්, "Write to DB Step" එකක් වගේ Steps කිහිපයක් තියෙන්න පුළුවන්.
- ItemReader: මේකෙන් කරන්නේ දත්ත කියවන එක. Data source එකක් (CSV file, database, XML file, REST API) එකකින් item by item data කියවනවා.
- ItemProcessor: මේක optional component එකක්. ItemReader එකෙන් කියවන ලද data item එකක් transform කරන්න, filter කරන්න, validate කරන්න මේක පාවිච්චි කරනවා. උදාහරණයක් විදිහට, Customer නමක් uppercase කරන්න පුළුවන්.
- ItemWriter: මේකෙන් කරන්නේ process කරපු data items ටික data sink එකකට (database, another CSV file, message queue) ලියන එක.
මේ core components වලට අමතරව තව Management components කිහිපයකුත් තියෙනවා:
- JobLauncher: Job එකක් start කරන්න මේක පාවිච්චි කරනවා.
- JobRepository: මේක තමයි Spring Batch වල heart එක. Job එකක් run කරපු හැම වෙලාවෙම ඒකේ status එක, progress එක වගේ metadata ටික database එකක store කරගන්නේ මේකෙන්. Job එකක් restart කරන්න, monitor කරන්න මේ information එක වැදගත් වෙනවා.
- JobExplorer: JobRepository එකේ තියෙන data ටික explore කරන්න මේක පාවිච්චි කරනවා.
මේ components ටික එකට එකතු වෙලා තමයි විශාල දත්ත කන්දරාවක් විශ්වාසදායක විදිහට process කරන්න අවශ්ය framework එක සපයන්නේ.
CSV File එකක් කියවලා, Process කරලා, ආයෙ ලියමු! (Let's Read, Process, and Write a CSV File!)
දැන් අපි බලමු practical scenario එකක්. අපි CSV file එකක තියෙන Customer data ටිකක් කියවලා, ඒකේ තියෙන names ටික uppercase කරලා, අලුත් CSV file එකකට ලියමු. මේකට අපි Spring Boot application එකක් පාවිච්චි කරනවා.
Prerequisites:
- Java 11 or higher
- Maven or Gradle
- Your favorite IDE (IntelliJ IDEA, VS Code, Eclipse)
Step 1: Project Setup
Spring Initializr (start.spring.io
) එකට ගිහින් අලුත් Spring Boot project එකක් හදාගන්න. Dependencies විදිහට මේවා add කරගන්න:
- Spring Batch
- Spring Boot DevTools (optional, for faster restarts)
- H2 Database (JobRepository එකට, in-memory database එකක් නිසා setup ලේසියි)
ඔයාගේ pom.xml
එකේ dependency section එක මේ වගේ වෙයි:
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>
<dependency>
<groupId>com.h2database</groupId>
<artifactId>h2</artifactId>
<scope>runtime</scope>
</dependency>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-test</artifactId>
<scope>test</scope>
</dependency>
<dependency>
<groupId>org.springframework.batch</groupId>
<artifactId>spring-batch-test</artifactId>
<scope>test</scope>
</dependency>
</dependencies>
Step 2: Customer Data Model එක හදමු
අපි CSV එකේ තියෙන data ටික map කරගන්න Customer කියන POJO එක හදමු. මේකට getters, setters, constructors, සහ toString()
method එකක් add කරගන්න.
package com.example.springbatchcsv.model;
public class Customer {
private Long id;
private String firstName;
private String lastName;
private String email;
public Customer() {}
public Customer(Long id, String firstName, String lastName, String email) {
this.id = id;
this.firstName = firstName;
this.lastName = lastName;
this.email = email;
}
// Getters and Setters
public Long getId() {
return id;
}
public void setId(Long id) {
this.id = id;
}
public String getFirstName() {
return firstName;
}
public void setFirstName(String firstName) {
this.firstName = firstName;
}
public String getLastName() {
return lastName;
}
public void setLastName(String lastName) {
this.lastName = lastName;
}
public String getEmail() {
return email;
}
public void setEmail(String email) {
this.email = email;
}
@Override
public String toString() {
return "Customer{" +
"id=" + id +
", firstName='" + firstName + '\'' +
", lastName='" + lastName + '\'' +
", email='" + email + '\'' +
'}';
}
}
Step 3: Batch Configuration එක හදමු
මේක තමයි Job, Step, Reader, Processor, Writer define කරන තැන. @EnableBatchProcessing
annotation එක දාන්න අමතක කරන්න එපා. මේකෙන් Spring Batch වල core infrastructure එක enable වෙනවා.
package com.example.springbatchcsv.config;
import com.example.springbatchcsv.model.Customer;
import com.example.springbatchcsv.processor.CustomerProcessor;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.Step;
import org.springframework.batch.core.job.builder.JobBuilder;
import org.springframework.batch.core.repository.JobRepository;
import org.springframework.batch.core.step.builder.StepBuilder;
import org.springframework.batch.item.ItemProcessor;
import org.springframework.batch.item.ItemReader;
import org.springframework.batch.item.ItemWriter;
import org.springframework.batch.item.file.FlatFileItemReader;
import org.springframework.batch.item.file.FlatFileItemWriter;
import org.springframework.batch.item.file.builder.FlatFileItemReaderBuilder;
import org.springframework.batch.item.file.builder.FlatFileItemWriterBuilder;
import org.springframework.batch.item.file.mapping.BeanWrapperFieldSetMapper;
import org.springframework.batch.item.file.mapping.DefaultLineMapper;
import org.springframework.batch.item.file.transform.DelimitedLineTokenizer;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.io.ClassPathResource;
import org.springframework.core.io.FileSystemResource;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class BatchConfig {
// 1. ItemReader: CSV එක කියවන්න
@Bean
public FlatFileItemReader<Customer> customerReader() {
return new FlatFileItemReaderBuilder<Customer>()
.name("customerItemReader")
.resource(new ClassPathResource("customers.csv")) // input CSV file එක resources/ folder එකේ තියෙන්න ඕනේ
.delimited()
.names(new String[]{"id", "firstName", "lastName", "email"})
.lineMapper(new DefaultLineMapper<>() {{
setLineTokenizer(new DelimitedLineTokenizer() {{
setNames(new String[]{"id", "firstName", "lastName", "email"});
}});
setFieldSetMapper(new BeanWrapperFieldSetMapper<Customer>() {{
setTargetType(Customer.class);
}});
}})
.build();
}
// 2. ItemProcessor: data process කරන්න
@Bean
public ItemProcessor<Customer, Customer> customerProcessor() {
return new CustomerProcessor(); // අපේ custom processor එක
}
// 3. ItemWriter: processed data ලියන්න
@Bean
public FlatFileItemWriter<Customer> customerWriter() {
return new FlatFileItemWriterBuilder<Customer>()
.name("customerItemWriter")
.resource(new FileSystemResource("output/processed_customers.csv")) // output path එක
.delimited()
.names(new String[]{"id", "firstName", "lastName", "email"})
.build();
}
// 4. Step: Reader, Processor, Writer එකට එකතු කරන්න
@Bean
public Step step1(JobRepository jobRepository, PlatformTransactionManager transactionManager,
ItemReader<Customer> customerReader, ItemProcessor<Customer, Customer> customerProcessor,
ItemWriter<Customer> customerWriter) {
return new StepBuilder("step1", jobRepository)
.<Customer, Customer>chunk(10) // 10 records බැගින් process කරනවා
.reader(customerReader)
.processor(customerProcessor)
.writer(customerWriter)
.transactionManager(transactionManager)
.build();
}
// 5. Job: Step එක run කරන්න
@Bean
public Job importUserJob(JobRepository jobRepository, Step step1) {
return new JobBuilder("importUserJob", jobRepository)
.flow(step1)
.end()
.build();
}
}
Step 4: Custom ItemProcessor එක හදමු
මේක තමයි Customer object එකේ firstName සහ lastName uppercase කරන්න පාවිච්චි කරන processor එක.
package com.example.springbatchcsv.processor;
import com.example.springbatchcsv.model.Customer;
import org.springframework.batch.item.ItemProcessor;
public class CustomerProcessor implements ItemProcessor<Customer, Customer> {
@Override
public Customer process(Customer customer) throws Exception {
final String transformedFirstName = customer.getFirstName().toUpperCase();
final String transformedLastName = customer.getLastName().toUpperCase();
final Customer transformedCustomer = new Customer(
customer.getId(),
transformedFirstName,
transformedLastName,
customer.getEmail()
);
System.out.println("Transforming customer: " + customer.getFirstName() + " to " + transformedFirstName);
return transformedCustomer;
}
}
Step 5: Input CSV File එක හදමු
src/main/resources/
folder එකේ customers.csv
කියලා file එකක් හදලා මේ data ටික එකට දාන්න:
id,firstName,lastName,email
1,john,doe,[email protected]
2,jane,smith,[email protected]
3,peter,jones,[email protected]
4,sara,lee,[email protected]
Step 6: Application Runner එක හදමු
මේකෙන් කරන්නේ Spring Boot application එක start වෙනකොටම අපේ batch job එක trigger කරන එක. Production වලදී මේක cron jobs, message queues, එහෙමත් නැත්නම් වෙන event එකක් හරහා trigger කරනවා.
package com.example.springbatchcsv;
import org.springframework.batch.core.Job;
import org.springframework.batch.core.JobParameters;
import org.springframework.batch.core.JobParametersBuilder;
import org.springframework.batch.core.launch.JobLauncher;
import org.springframework.boot.CommandLineRunner;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;
import org.springframework.context.annotation.Configuration;
@SpringBootApplication
@Configuration // Make sure this is a configuration class
public class SpringBatchCsvApplication implements CommandLineRunner {
private final JobLauncher jobLauncher;
private final Job importUserJob;
public SpringBatchCsvApplication(JobLauncher jobLauncher, Job importUserJob) {
this.jobLauncher = jobLauncher;
this.importUserJob = importUserJob;
}
public static void main(String[] args) {
SpringApplication.run(SpringBatchCsvApplication.class, args);
}
@Override
public void run(String... args) throws Exception {
JobParameters jobParameters = new JobParametersBuilder()
.addLong("time", System.currentTimeMillis())
.toJobParameters();
jobLauncher.run(importUserJob, jobParameters);
}
}
Step 7: Run කරලා බලමු!
දැන් ඔයාගේ IDE එකෙන් SpringBatchCsvApplication
class එක run කරන්න. Console එකේ output එක බැලුවොත්, transforming messages ටික දැකගන්න පුළුවන් වෙයි. Project root folder එකේ output
කියන folder එකක් හැදිලා, ඒක ඇතුළේ processed_customers.csv
කියන file එක හැදිලා ඇති. ඒක ඇරලා බැලුවොත්, names ටික uppercase වෙලා තියෙනවා දැකගන්න පුළුවන්.
id,firstName,lastName,email
1,JOHN,DOE,[email protected]
2,JANE,SMITH,[email protected]
3,PETER,JONES,[email protected]
4,SARA,LEE,[email protected]
පට්ට නේද? පොඩි code කෑල්ලකින් අපි ලොකු data processing job එකක් implement කළා!
වැදගත් ටිප්ස් සහ ප්රැක්ටිකල් කාරණා (Important Tips and Practical Considerations)
මේ අපි කරපු එක පොඩි example එකක් විතරයි. Production ready application එකකදී තව ගොඩක් දේවල් ගැන හිතන්න වෙනවා:
- Error Handling: Records process වෙද්දී errors ආවොත් ඒවා handle කරන්නේ කොහොමද? Skip policies, retry policies වගේ දේවල් Spring Batch වලට add කරන්න පුළුවන්.
- Restartability: Job එකක් අසාර්ථක වුණොත්, එතනින්ම ආයෙත් පටන් ගන්න පුළුවන් වෙන්න JobRepository එක හරියට configure කරන්න ඕනේ.
- Scalability: දත්ත ප්රමාණය ගොඩක් වැඩි වුණොත්, single thread එකකින් process කරන එක මදි වෙන්න පුළුවන්. මේකට multi-threading (
TaskExecutor
), partitioning (job එක Steps වලට කඩලා parallel process කරනවා), remote chunking (distributed systems වල chunks process කරනවා) වගේ concepts පාවිච්චි කරන්න පුළුවන්. - Monitoring: Spring Boot Actuator එක්ක Spring Batch job එකක status එක monitor කරන්න පුළුවන්. ඒ වගේම Spring Batch Admin වගේ tools පාවිච්චි කරන්නත් පුළුවන්.
- Transaction Management: එක් එක් chunk එක transaction එකක් ඇතුළත process වෙන නිසා, data consistency එක හැමවෙලේම maintain වෙනවා.
- Database for JobRepository: H2 in-memory database එකක් පාවිච්චි කළාට, production වලදී MySQL, PostgreSQL, Oracle වගේ persistent database එකක් තමයි පාවිච්චි කරන්නේ. ඒකෙන් Job execution metadata ටික permanent විදිහට save වෙනවා.
- When NOT to use Spring Batch: Real-time, low-latency data processing (e.g., streaming data, immediate responses) වලට Spring Batch එච්චර සුදුසු නෑ. ඒ වගේ වෙලාවට Spring Cloud Stream, Apache Kafka වගේ technologies තමයි සුදුසු. Spring Batch කියන්නේ scheduled, periodic data processing වලට හොඳම විසඳුමක්.
අවසන් වශයෙන් (Conclusion)
අද අපි Spring Batch කියන්නේ මොකක්ද, ඒකේ architecture එක, ඒ වගේම පොඩි practical example එකක් කරලා CSV file එකක් කියවලා, process කරලා, ආයෙත් CSV file එකකට ලියන්නේ කොහොමද කියලා බැලුවා. විශාල දත්ත කන්දරාවක් එක්ක වැඩ කරනකොට Spring Batch කියන්නේ අපිට ගොඩක් වටිනා tool එකක් කියලා ඔයාලට දැන් තේරෙන්න ඇති. ඒකෙන් අපේ applications වල reliability එක, scalability එක, maintainability එක වැඩි කරනවා.
මේ article එක ඔයාලට වැදගත් වෙන්න ඇති කියලා හිතනවා. පුළුවන් නම් මේ code එක ඔයාලගේ computer එකේ run කරලා බලන්න. මොනවා හරි ගැටලුවක් ආවොත්, එහෙමත් නැත්නම් අලුත් දෙයක් ඉගෙන ගත්තා නම්, පහලින් comment එකක් දාන්න අමතක කරන්න එපා. මේ වගේ තව මොනවා ගැනද දැනගන්න කැමති කියලත් කියන්න.
ආයෙත් හම්බවෙමු!