Loading
  • LIGHT

  • DARK

ROUTE

ルートゼロの
アクティビティ

Spring Boot Batch現場導入ガイド|バッチ処理の設計・実装・エラー対策がこれ一つでわかる!

3

はじめに

「夜間のデータ集計、Spring Boot Batchで実装してみて」――突然そんなタスクが降ってきて、 どこから手をつければいいのか悩んだ経験はありませんか?

JobStepChunk……断片的な情報だけでは全体像が見えず、本当に本番運用できるのか不安になりがち。

私たちも「腹落ち」しにくいと感じてきました。 そこでこの記事では、現場目線で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.propertiesspring.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で自動テストも簡単

まずは手元のプロジェクトで、 実際に動かしてみることが一番の近道です。 ぜひコードをコピペして、まずは動かしてみてください。


もっとルートゼロを知りたいなら

DISCOVER MORE