はじめに
「夜間のデータ集計、Spring Boot Batchで実装してみて」――突然そんなタスクが降ってきて、 どこから手をつければいいのか悩んだ経験はありませんか?
Job、Step、Chunk……断片的な情報だけでは全体像が見えず、本当に本番運用できるのか不安になりがち。
私たちも「腹落ち」しにくいと感じてきました。 そこでこの記事では、現場目線でSpring Boot Batchの実践ノウハウをまとめます。
図解で理解→即コピペで動作→本番必須の運用テクまで、一気に“腹落ち”を狙います。
1. まず押さえたい!Spring Boot Batchの3つのコア概念【図解あり】
「Spring Boot Batchって何?」という疑問、 よくある断片情報では、実務ではかえって混乱しませんか?
私たちが腹落ちするには、 「Job」「Step」「JobRepository」の3本柱を 料理の手順にたとえてイメージするとスッと理解できます。
- Job:バッチ全体の“カレーを作る”タスク本体
- Step:その中の“野菜を切る”“肉を炒める”など各工程
- JobRepository:進捗・履歴を記録する“レシピ台帳”
用語解説:Spring Boot Batch Javaでバッチ処理(定期的なデータ集計や一括更新など)を効率よく実装できるフレームワーク。業務システムでよく使われる。
用語解説:Job バッチ処理全体の「親」単位。例えば「売上集計バッチ」など、まとまった業務処理の本体。
用語解説:Step Jobの中の個別工程。データ読込・加工・書出しなど、処理の手順ごとに分割できる。
用語解説:Chunk 大量データを一定件数ずつ分割して処理する仕組み。メモリ効率やエラー耐性に優れる。
用語解説:JobRepository バッチの実行履歴や進捗をデータベースに記録する仕組み。途中失敗時の再開や運用管理に必須。
(Spring Bootの依存管理やpom.xmlについては『Spring Boot pom.xml徹底解説|2025年版 依存管理・バージョン競合の全対策』をご参照ください)
Job ― バッチ全体の“親”
バッチ処理の最上位単位がJob。 「日次売上集計バッチ」など、ひとまとまりの業務処理をまるごとカプセル化します。
Jobは必ず1つ以上のStepで構成され、どのStepをどの順番で実行するか定義できます。
Step ― 個別の“手順”担当(Tasklet/Chunk)
Stepはバッチ処理の構成要素。 実は2種類のモデルがあります。
- Taskletモデル:一度だけ実行する単純作業(例:事前ファイル削除)
- Chunkモデル:大量データを“少しずつ分割”して読込み→加工→書出し(主役はこちら)
(Spring Bootのパラメータ受け取りやDI/IoCについては『Spring Boot のパラメータ受け取り|@ModelAttribute と @RequestBody の違いと使い分け』もご参照ください)
用語解説:Tasklet 1回だけ実行する単純な処理(例:ファイル削除や初期化など)を担当するStepの実装方式。
用語解説:Chunkモデル データを分割(チャンク)して、読込→加工→書出しを繰り返す方式。大量データ処理の主役。
JobRepository ― 実行記録の“黒子”
バッチの実行状態(開始・成功・失敗など)をDBに永続化し、 途中失敗時にも「どこから再開?」を判断できます。 これがSpring Batchの“堅牢さ”の根幹です。
2. 【手を動かす】最小構成!TaskletモデルでHello Worldバッチ
「とりあえずバッチを“動かす”には?」 最小構成のTaskletモデルで“Hello, World!”を出力してみます。
(Spring Bootの設定ファイルやエラー対策については『Spring Boot NullPointerException完全対策|3大原因と実装例まとめ』もご参照ください)
用語解説:build.gradle Javaプロジェクトの依存ライブラリや設定を管理するファイル。Spring Boot Batch利用時は必須。
用語解説:Bean定義 Springで管理する部品(JobやStepなど)をプログラム上で登録する仕組み。
用語解説:application.properties Spring Bootの設定ファイル。バッチの自動起動やDB接続情報などを記述する。
build.gradleの設定
dependencies {
implementation("org.springframework.boot:spring-boot-starter-batch")
runtimeOnly("com.h2database:h2")
}
Job/StepのBean定義と実行例
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.core.step.tasklet.Tasklet;
import org.springframework.batch.repeat.RepeatStatus;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.transaction.PlatformTransactionManager;
@Configuration
public class HelloWorldJobConfig {
@Bean
public Step helloWorldStep(JobRepository jobRepository, PlatformTransactionManager transactionManager) {
return new StepBuilder("helloWorldStep", jobRepository)
.tasklet((contribution, chunkContext) -> {
System.out.println("Hello, Spring Boot Batch!");
return RepeatStatus.FINISHED;
}, transactionManager)
.build();
}
@Bean
public Job helloWorldJob(JobRepository jobRepository, Step helloWorldStep) {
return new JobBuilder("helloWorldJob", jobRepository)
.start(helloWorldStep)
.build();
}
}
application.propertiesで spring.batch.job.enabled=falseを設定し、起動すると、 「Hello, Spring Boot Batch!」がコンソールに出力されます。
3. 本命はこれ!ChunkモデルでDB→CSVエクスポート
「なぜChunkモデルが推されるのか?」 100万件のデータを一気にメモリに載せると、OutOfMemoryの危険大。 Chunkモデルは「1000件ずつ処理→書き出し」を繰り返し、
メモリ使用量を一定に抑えます。
(JPAやnativeQueryの使い分けについては『Spring Boot Repository徹底解説|JPA・nativeQueryの使い方と失敗例』もご参照ください)
用語解説:ItemReader データベースやファイルなどからデータを読み込む部品。Chunkモデルの最初の工程。
用語解説:ItemProcessor 読み込んだデータを加工・変換・フィルタする部品。不要データの除外なども担当。
用語解説:ItemWriter 加工済みデータをファイルやDBに書き出す部品。CSV出力などで利用。
ItemReader:JPA + Pagingで効率読込
@Bean
public JpaPagingItemReader<User> userItemReader(EntityManagerFactory emf) {
return new JpaPagingItemReaderBuilder<User>()
.name("userItemReader")
.entityManagerFactory(emf)
.queryString("SELECT u FROM User u ORDER BY u.id")
.pageSize(1000)
.build();
}
ItemProcessor:データ変換・フィルタもここ
public class UserProcessor implements ItemProcessor<User, UserCsvDto> {
@Override
public UserCsvDto process(User user) {
if (!user.isActive()) {
return null; // 無効ユーザーはスキップ
}
UserCsvDto dto = new UserCsvDto();
dto.setName(user.getFirstName() + " " + user.getLastName());
dto.setEmail(user.getEmail());
return dto;
}
}
ItemWriter:CSV出力もシンプルに
@Bean
public FlatFileItemWriter<UserCsvDto> userItemWriter() {
return new FlatFileItemWriterBuilder<UserCsvDto>()
.name("userItemWriter")
.resource(new FileSystemResource("output/users.csv"))
.delimited()
.names("name", "email")
.headerCallback(writer -> writer.write("Name,Email"))
.build();
}
4. 本番品質!エラー処理とバッチテスト
「バッチは“動くだけ”じゃダメ。止まらず回復できる設計が要!」 現場で効く、代表的なエラー耐性手法を紹介します。
(Spring Bootテスト設計やTDDについては『Spring Bootテスト設計入門:TDD×モック×CI自動化ガイド』もご参照ください)
用語解説:Skip 特定の例外発生時に、そのデータだけスキップして処理を継続する仕組み。エラー耐性向上に有効。
用語解説:Retry 一時的なエラー(DBロックなど)が発生した場合、指定回数まで再試行する仕組み。
用語解説:JobLauncherTestUtils Spring BatchのJobをテスト自動化するためのユーティリティ。バッチの品質担保に役立つ。
✅ 方法1:特定例外をスキップ(Skip)
@Bean
public Step chunkStep(..., ItemReader<User> reader, ItemProcessor<User, UserCsvDto> processor, ItemWriter<UserCsvDto> writer) {
return new StepBuilder("chunkStep", jobRepository)
.<User, UserCsvDto>chunk(1000, transactionManager)
.reader(reader)
.processor(processor)
.writer(writer)
.faultTolerant()
.skip(IllegalArgumentException.class)
.skipLimit(10)
.build();
}
✅ 方法2:リトライで一時的なエラーに備える
.retry(DeadlockLoserDataAccessException.class)
.retryLimit(3)
JobLauncherTestUtilsでテスト自動化
@SpringBootTest
@SpringBatchTest
class MyBatchJobTests {
@Autowired
private JobLauncherTestUtils jobLauncherTestUtils;
@Autowired
private Job myJob;
@Test
void testMyJob() throws Exception {
this.jobLauncherTestUtils.setJob(myJob);
JobExecution jobExecution = jobLauncherTestUtils.launchJob();
assertEquals(BatchStatus.COMPLETED, jobExecution.getStatus());
}
}
5. 応用編:マルチスレッド処理・Spring Boot 3対応
- TaskExecutorでStepをマルチスレッド化し、さらに高速化可能(※ItemReaderはスレッドセーフ必須に注意)
- Spring Boot 3.xでは、@EnableBatchProcessingは不要→ 依存追加で自動有効化されます
(Spring Boot×Dockerの開発環境構築やエラー対策については『Docker Composeで「DBに繋がらない!」を防ぐ。Spring Boot開発の失敗パターン総まとめ』もご参照ください)
用語解説:TaskExecutor 複数スレッドでStepを並列実行するための仕組み。処理速度向上に有効だが、スレッド安全性に注意。
用語解説:@Scheduled 指定した日時・周期でバッチJobを自動実行するSpringのアノテーション。
用語解説:JobParameters Job実行時に渡すパラメータ。日時やIDなど、バッチごとに異なる値を指定できる。
Jobの定期実行は@Scheduled+JobParametersで
@Scheduled(cron = "0 0 2 * * *")
public void launchBatch() {
JobParameters params = new JobParametersBuilder()
.addLong("time", System.currentTimeMillis())
.toJobParameters();
jobLauncher.run(job, params);
}
まとめ
- Job/Step/JobRepositoryの関係性を理解すれば腹落ち
- Tasklet:小タスク、Chunk:大量データの主役
- Skip/Retryで“止まらない”バッチに
- JobLauncherTestUtilsで自動テストも簡単
まずは手元のプロジェクトで、 実際に動かしてみることが一番の近道です。 ぜひコードをコピペして、まずは動かしてみてください。