従来、メタテーブルを永続化しなくするためにMapJobRepositoryFactoryBean
を使う事があったがspring-batch v5.0で削除予定になったようだ。
* @deprecated as of v4.3 in favor or using the {@link JobRepositoryFactoryBean} * with an in-memory database. Scheduled for removal in v5.0. */ @Deprecated public class MapJobRepositoryFactoryBean extends AbstractJobRepositoryFactoryBean {
その対策は上記javadocにある通りインメモリDB使ってね、て事らしい。他にデータソースが無ければ以下のようにH2などの依存性追加するだけでよい。springアプリケーションと共にH2も終了するので事実上永続化はしない。
runtimeOnly 'com.h2database:h2'
複数データソースがある場合、というか、大抵はメタデータ用とメイン用の2つ以上のデータソースがあると思われる。この場合は、これまでの複数データソースの場合と同様、メタデータ用のH2データソースとそれ以外を用意すればよい。メタデータ用のデータソースには@BatchDataSource
を付与する。
import javax.sql.DataSource; import org.h2.jdbcx.JdbcDataSource; import org.springframework.boot.autoconfigure.batch.BatchDataSource; import org.springframework.boot.jdbc.DataSourceBuilder; import org.springframework.context.annotation.Bean; import org.springframework.context.annotation.Configuration; import org.springframework.context.annotation.Primary; @Configuration public class DatasourceConfig { @Bean @Primary public DataSource primaryDs() { return DataSourceBuilder .create() .url("jdbc:oracle:thin:system/oracle@localhost:11521/XEPDB1") .username("system") .password("oracle") .build(); } @BatchDataSource @Bean public DataSource dataSource() { JdbcDataSource ds = new JdbcDataSource(); ds.setURL("jdbc:h2:mem:test;DB_CLOSE_DELAY=-1;DB_CLOSE_ON_EXIT=TRUE"); ds.setUser("sa"); ds.setPassword(""); return ds; } }
上記はインメモリモードで起動しているが、ファイルモードも選択肢になると思う。コンテナ破棄でファイルも削除が最近は多いだろうし、インメモリで持ちたく無ければファイルもありだろうか?
ただ、常時起動の場合にはインメモリと言えどその影響が気になる。メモリ容量の圧迫もだが、デフォルトのDDLはインデックスを張らないので速度低下も懸念される。もっとも、相当貯めこまないと目に見える影響は出てこないだろうし、再起動という運用で回避も十分現実的と思う。
でまぁ、以下は完全に思いつきでマッタク検証してないのだけど。どうせメタデータ使わないならジョブ実行後に削除で良いんでないかな、と。
@Bean public JobExecutionListener list(DataSource ds) { JdbcTemplate t = new JdbcTemplate(ds); return new JobExecutionListener() { @Override public void beforeJob(JobExecution jobExecution) { } @Override public void afterJob(JobExecution jobExecution) { // 他テーブルは省略 t.update("delete from BATCH_JOB_EXECUTION_CONTEXT where JOB_EXECUTION_ID = " + jobExecution.getId()); } }; }