Episode ini membahas pekerjaan terjadwal dan pemrosesan data dalam jumlah besar: Spring Batch dengan job, step, reader, processor, dan writer; scheduled task dengan @Scheduled dan cron expression; serta eksekusi asynchronous dengan task executor.

Tidak semua pekerjaan terjadi karena request pengguna. Membersihkan data lama, mengirim email, memproses jutaan baris file, atau memperbarui laporan adalah pekerjaan yang berjalan di latar belakang. Episode 11 membahas batch processing dan scheduling.
Kalian akan belajar memakai Spring Batch untuk pemrosesan data bervolume besar dengan job dan step, menjadwalkan tugas dengan @Scheduled, serta mengeksekusi tugas secara asynchronous agar tidak memblokir thread utama.
Spring menyediakan scheduling sederhana. Aktifkan dengan @EnableScheduling di kelas utama, lalu tandai method dengan @Scheduled:
@Component
public class ReportTask {
private static final Logger log =
LoggerFactory.getLogger(ReportTask.class);
@Scheduled(fixedRate = 60000)
public void generateDailyReport() {
log.info("Menjalankan pembuatan laporan");
// logika bisnis
}
}fixedRate = 60000 menjalankan method setiap 60 detik, dihitung dari awal eksekusi sebelumnya. Ada juga fixedDelay yang menghitung dari akhir eksekusi, serta initialDelay untuk penundaan pertama.
Untuk jadwal yang lebih kompleks, gunakan cron expression — enam atau tujuh segmen untuk detik, menit, jam, hari, bulan, dan hari dalam minggu. Expression 0 0 0 * * * berarti setiap hari pukul 00:00:00. Contoh lain: 0 0 2 * * MON-FRI untuk pukul 02:00 di hari kerja. Pahami urutan segmen cron karena sering menjadi sumber kesalahan konfigurasi.
Untuk pemrosesan data bervolume besar — misalnya membaca jutaan baris file dan menyimpannya ke database — gunakan Spring Batch. Strukturnya terdiri dari Job yang berisi satu atau lebih Step. Setiap Step memakai ItemReader untuk membaca, ItemProcessor untuk memproses, dan ItemWriter untuk menulis.
Tambahkan dependency:
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-batch</artifactId>
</dependency>Contoh job yang membaca data dari file CSV dan menyimpannya ke database:
@Configuration
public class BatchConfig {
@Bean
public Job importItemJob(JobRepository repo, Step step) {
return new JobBuilder("importItemJob", repo)
.start(step)
.build();
}
@Bean
public Step importStep(JobRepository repo,
PlatformTransactionManager tx,
ItemReader<Item> reader,
ItemWriter<Item> writer) {
return new StepBuilder("importStep", repo)
.<Item, Item>chunk(100, tx)
.reader(reader)
.writer(writer)
.build();
}
}Step di atas memproses data dalam chunk berukuran 100 — membaca 100 item, lalu menulisnya dalam satu transaksi. Ukuran chunk menentukan keseimbangan antara penggunaan memori dan jumlah transaksi.
ItemReader dan ItemWriter bisa berupa implementasi bawaan maupun custom. Contoh paling umum memakai FlatFileItemReader untuk file CSV:
@Bean
public FlatFileItemReader<Item> reader() {
return new FlatFileItemReaderBuilder<Item>()
.name("itemReader")
.resource(new ClassPathResource("data/items.csv"))
.delimited()
.names("name", "price")
.targetType(Item.class)
.build();
}Dengan pola ini, Spring Batch menangani chunking, transaksi, dan restart otomatis — jika job gagal di tengah jalan, job bisa dilanjutkan dari titik terakhir yang sukses.
Salah satu keunggulan Spring Batch adalah restartability: status eksekusi disimpan di tabel metadata Spring Batch, sehingga job yang gagal bisa dijalankan ulang tanpa mengulang chunk yang sudah sukses. Ini penting untuk pemrosesan yang memakan waktu lama.
Jalankan job yang sama dengan parameter berbeda — misalnya tanggal laporan — lewat job parameter:
./mvnw spring-boot:run -Dspring-boot.run.arguments=--date=2026-08-10Parameter --date bisa diakses di reader dan processor lewat @StepScope dan @Value, memungkinkan job yang sama dipakai untuk input yang berbeda-beda.
Tugas yang memakan waktu tidak boleh memblokir request pengguna. Aktifkan @EnableAsync, lalu tandai method dengan @Async:
@SpringBootApplication
@EnableAsync
public class BelajarSpringBootApplication {
// ...
}@Service
public class NotificationService {
@Async
public void sendWelcomeEmail(String email) {
// mengirim email tidak memblokir pemanggil
}
}Method @Async dieksekusi di thread pool terpisah dan mengembalikan kontrol ke pemanggil secara langsung. Pastikan pemanggilan dilakukan antar bean — self-invocation tidak akan memicu perilaku async.
Atur ukuran thread pool untuk kontrol yang lebih baik:
spring:
task:
execution:
pool:
core-size: 4
max-size: 16
queue-capacity: 100Konfigurasi di atas membatasi thread pool antara 4 hingga 16 thread dengan antrean 100 task. Ukuran pool harus disesuaikan dengan kapasitas server dan sifat pekerjaan — terlalu kecil menyebabkan antrean, terlalu besar membebani memori.
Episode 11 membekali kalian dengan pemrosesan terjadwal: scheduled task dengan @Scheduled dan cron expression, Spring Batch untuk pemrosesan data bervolume besar dengan job, step, reader, processor, dan writer, serta eksekusi asynchronous dengan @Async dan task executor.
Inti yang harus dibawa pulang:
@EnableScheduling, lalu gunakan @Scheduled.@Async mengeksekusi tugas di thread pool tanpa memblokir pemanggil.Di episode 12 selanjutnya kita akan membahas security dasar dan auth — Spring Security dan filter chain, konfigurasi authentication manager dan user details, form login dan basic auth, serta perlindungan CSRF, CORS, dan security headers.