Spring Cloud Task-Batch中saveRelationship未写入TASK_TASK_BATCH数据
Spring Batch 部署在SCDF中TASK_TASK_BATCH表无数据写入问题解决方案
问题现象
- 本地SCDF环境部署的Spring Batch应用整体运行正常:任务流程可完整执行,所有Batch、Task元数据表均能正常写入数据,仅
TASK_TASK_BATCH表无关联记录 - 日志中可观测到
TaskBatchExecutionListener输出的The job execution [id] was run within the task execution [id]日志,证明监听器逻辑已触发,但内部taskBatchDao.saveRelationship方法的写入操作未实际落库 - 临时方案为自定义JobListener,在显式绑定元数据源事务管理器的事务中手动写入该表记录,但该方案侵入性较强,不符合框架原生设计逻辑
根因
该问题本质是事务管理器/数据源不匹配导致的写入操作未提交或写入到错误的数据源:TaskBatchExecutionListener中保存Task执行ID与Job执行ID关联关系的逻辑,默认会从当前上下文获取事务管理器执行持久化。如果项目中存在多数据源配置,或是Spring Batch、Spring Cloud Task各自自动配置拿到的事务管理器、元数据源不一致,就会出现两种异常情况:
- 写入操作拿到的是业务数据源的连接,关联数据写到了业务库而非元数据库,元数据库的
TASK_TASK_BATCH表自然查不到数据 - 写入操作加入的作业执行事务在后续流程中触发回滚,关联记录被连带回滚,最终没有持久化到表中
由于监听器本身的日志打印逻辑不依赖事务提交,所以会出现日志打印正常但数据没写入的现象。
修复方案
按优先级依次排查调整即可:
- 显式统一Task与Batch的元数据配置
自定义TaskConfigurer,强制指定Spring Cloud Task使用和Spring Batch完全一致的元数据源、元数据事务管理器,避免自动配置推断错误:
注意上述代码中注入的@Bean public TaskConfigurer taskConfigurer( @Qualifier("batchMetaDataSource") DataSource metaDataSource, @Qualifier("batchTransactionManager") PlatformTransactionManager metaTxManager) { return new DefaultTaskConfigurer(metaDataSource) { @Override public PlatformTransactionManager getTransactionManager() { return metaTxManager; } }; }batchMetaDataSource、batchTransactionManager需要和你自定义BatchConfigurer时指定的作业元数据源、作业事务管理器完全一致,保证两边元数据操作走同一个连接、同一个事务边界。 - 校验
TaskBatchDao的数据源绑定
如果项目中曾自定义TaskBatchDaoBean,需要确认其内部使用的JdbcTemplate是绑定元数据源的实例,而非业务数据源的JdbcTemplate;如果没有自定义过该Bean,直接跳过这一步即可。 - 避免异常回滚抹除关联记录
如果需要在Job执行失败时也保留Task与Job的关联关系,可在配置文件中添加如下配置,避免Job失败回滚时把已写入的关联记录一并回滚:
该配置不会改变Job本身的执行状态记录,仅保证关联关系写入逻辑不会被作业失败的回滚逻辑影响。spring.cloud.task.batch.fail-on-job-failure=false
调整完成后重启应用,触发一次任务执行即可看到TASK_TASK_BATCH表自动写入正确的关联记录,不需要再自定义监听器手动写数据。
内容的提问来源于stack exchange,提问作者dgerhardt
相关产品推荐
相关产品推荐

