事象
Spring batchでBATCH_STEP_EXECUTIONへの結果格納時にエラー
Spring batchのジョブ上で発生した例外は、異常終了の状態でSpring batchの管理するテーブルに情報がINSERTされるが、
DB2でDataIntegrityViolationExceptionが発生した。
エラー内容
[2018/06/11 15:50:04] [main] [o.s.b.f.x.XmlBeanDefinitionReader] [INFO ] Loading XML bean definitions from class path resource [org/springframework/jdbc/support/sql-error-codes.xml] [2018/06/11 15:50:04] [main] [o.s.j.s.SQLErrorCodesFactory] [INFO ] SQLErrorCodes loaded: [DB2, Derby, H2, HSQL, Informix, MS-SQL, MySQL, Oracle, PostgreSQL, Sybase, Hana] [2018/06/11 15:50:04] [main] [o.s.b.c.s.AbstractStep] [ERROR] Encountered an error saving batch meta data for step hoge.step01 in job hoge. This job is now in an unknown state and should not be restarted. org.springframework.dao.DataIntegrityViolationException: PreparedStatementCallback; SQL [UPDATE BATCH_STEP_EXECUTION set START_TIME = ?, END_TIME = ?, STATUS = ?, COMMIT_COUNT = ?, READ_COUNT = ?, FILTER_COUNT = ?, WRITE_COUNT = ?, EXIT_CODE = ?, EXIT_MESSAGE = ?, VERSION = ?, READ_SKIP_COUNT = ?, PROCESS_SKIP_COUNT = ?, WRITE_SKIP_COUNT = ?, ROLLBACK_COUNT = ?, LAST_UPDATED = ? where STEP_EXECUTION_ID = ? and VERSION = ?]; DB2 SQL Error: SQLCODE=-302, SQLSTATE=22001, SQLERRMC=null, DRIVER=4.11.77; nested exception is com.ibm.db2.jcc.am.SqlDataException: DB2 SQL Error: SQLCODE=-302, SQLSTATE=22001, SQLERRMC=null, DRIVER=4.11.77 at org.springframework.jdbc.support.SQLExceptionSubclassTranslator.doTranslate(SQLExceptionSubclassTranslator.java:82) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:73) at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:81) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:649) at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:870) at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:931) at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:936) at org.springframework.batch.core.repository.dao.JdbcStepExecutionDao.updateStepExecution(JdbcStepExecutionDao.java:244) at org.springframework.batch.core.repository.support.SimpleJobRepository.update(SimpleJobRepository.java:191) at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) at sun.reflect.NativeMethodAccessorImpl.invoke(Unknown Source) at sun.reflect.DelegatingMethodAccessorImpl.invoke(Unknown Source) at java.lang.reflect.Method.invoke(Unknown Source) at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:333) at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:190) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:157) at org.springframework.transaction.interceptor.TransactionInterceptor$1.proceedWithInvocation(TransactionInterceptor.java:99) at org.springframework.transaction.interceptor.TransactionAspectSupport.invokeWithinTransaction(TransactionAspectSupport.java:282) at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:96) at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:179) at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:213) at com.sun.proxy.$Proxy11.update(Unknown Source) at org.springframework.batch.core.step.AbstractStep.execute(AbstractStep.java:260) at org.springframework.batch.core.job.SimpleStepHandler.handleStep(SimpleStepHandler.java:148) at org.springframework.batch.core.job.flow.JobFlowExecutor.executeStep(JobFlowExecutor.java:64) at org.springframework.batch.core.job.flow.support.state.StepState.handle(StepState.java:67) at org.springframework.batch.core.job.flow.support.SimpleFlow.resume(SimpleFlow.java:169) at org.springframework.batch.core.job.flow.support.SimpleFlow.start(SimpleFlow.java:144) at org.springframework.batch.core.job.flow.FlowJob.doExecute(FlowJob.java:134) at org.springframework.batch.core.job.AbstractJob.execute(AbstractJob.java:306) at org.springframework.batch.core.launch.support.SimpleJobLauncher$1.run(SimpleJobLauncher.java:135) at org.springframework.core.task.SyncTaskExecutor.execute(SyncTaskExecutor.java:50) at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:128) at org.springframework.batch.core.launch.support.CommandLineJobRunner.start(CommandLineJobRunner.java:362) at org.springframework.batch.core.launch.support.CommandLineJobRunner.main(CommandLineJobRunner.java:592) Caused by: com.ibm.db2.jcc.am.SqlDataException: DB2 SQL Error: SQLCODE=-302, SQLSTATE=22001, SQLERRMC=null, DRIVER=4.11.77 at com.ibm.db2.jcc.am.gd.a(gd.java:668) at com.ibm.db2.jcc.am.gd.a(gd.java:60) at com.ibm.db2.jcc.am.gd.a(gd.java:127) at com.ibm.db2.jcc.am.jn.b(jn.java:2230) at com.ibm.db2.jcc.am.jn.c(jn.java:2213) at com.ibm.db2.jcc.t4.cb.k(cb.java:369) at com.ibm.db2.jcc.t4.cb.a(cb.java:61) at com.ibm.db2.jcc.t4.q.a(q.java:50) at com.ibm.db2.jcc.t4.sb.b(sb.java:226) at com.ibm.db2.jcc.am.kn.oc(kn.java:2930) at com.ibm.db2.jcc.am.kn.b(kn.java:3876) at com.ibm.db2.jcc.am.kn.b(kn.java:4047) at com.ibm.db2.jcc.am.kn.gc(kn.java:743) at com.ibm.db2.jcc.am.kn.executeUpdate(kn.java:722) at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:98) at org.apache.commons.dbcp2.DelegatingPreparedStatement.executeUpdate(DelegatingPreparedStatement.java:98) at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:877) at org.springframework.jdbc.core.JdbcTemplate$2.doInPreparedStatement(JdbcTemplate.java:870) at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:633) ... 31 common frames omitted [2018/06/11 15:50:04] [main] [o.s.b.c.l.s.SimpleJobLauncher] [INFO ] Job: [FlowJob: [name=hoge]] completed with the following parameters: [{puge=hogehoge1, jsr_batch_run_id=1286}] and the following status: [UNKNOWN] [2018/06/11 15:50:04] [main] [o.s.c.s.ClassPathXmlApplicationContext] [INFO ] Closing org.springframework.context.support.ClassPathXmlApplicationContext@1565ec2: startup date [Mon Jun 11 15:49:57 JST 2018]; root of context hierarchy
原因
DB2で作成したSpring batch管理用のテーブル(BATCH_STEP_EXECUTION)のカラムサイズが小さくて、例外の内容の格納できずに異常終了が発生するため。
exit_messageカラムとかが該当
解決策
job-repositoryタグにmax-varchar-length属性を追加する。
そうすることで、例外の取得文字数の最大をDB2で設定したカラム以下に収められ、例外の格納ができる。
DBの設定している文字コードによって1文字当たりのバイト数も変わるのでそこも要チェック。
<job-repository id="jobRepository" data-source="dataSource" transaction-manager="transactionManager" isolation-level-for-create="SERIALIZABLE" table-prefix="BATCH_" max-varchar-length="1000"/>
参考
【Spring Batch】JobRepositoryへの保存時にカラムのサイズを超えてしまう
Configuring and Running a Job
コメントを書く