您能否告诉我在生产中的Spring Batch Application中应该使用哪个事务管理器?我正在使用Resourceless Transaction manager。好吗?从外部Oracle DB读取数据时,我遇到了这个问题
[org.springframework.scheduling.support.TaskUtils$LoggingErrorHandler] (pool-3130-thread-1) Unexpected error occurred in scheduled task.: org.springframework.transaction.CannotCreateTransactionException: Could not open JDBC Connection for transaction; nested exception is java.sql.SQLRecoverableException: Closed Connection
@Bean
public ResourcelessTransactionManager resourcelessTransactionManager() {
return new ResourcelessTransactionManager();
}
@Bean
public MapJobRepositoryFactoryBean mapJobRepositoryFactory(
ResourcelessTransactionManager txManager) throws Exception {
//LOGGER.info("Inside mapJobRepositoryFactory method");
MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean(txManager);
factory.setTransactionManager(txManager);
factory.setIsolationLevelForCreate("ISOLATION_READ_UNCOMMITTED");
factory.afterPropertiesSet();
return factory;
}
@Bean
public JobRepository jobRepository(
MapJobRepositoryFactoryBean factory) throws Exception {
//LOGGER.info("Inside jobRepository method");
return factory.getObject();
}
@Bean
public ThreadPoolTaskExecutor taskExecutor() {
ThreadPoolTaskExecutor taskExecutor = new ThreadPoolTaskExecutor();
taskExecutor.setCorePoolSize(5);
taskExecutor.setMaxPoolSize(10);
taskExecutor.setQueueCapacity(30);
return taskExecutor;
}
@Bean
public JobLauncher jobLauncher(JobRepository jobRepository,ThreadPoolTaskExecutor taskExecutor) {
//LOGGER.info("Inside jobLauncher method");
SimpleJobLauncher launcher = new SimpleJobLauncher();
launcher.setTaskExecutor(taskExecutor);
launcher.setJobRepository(jobRepository);
final SimpleAsyncTaskExecutor simpleAsyncTaskExecutor = new SimpleAsyncTaskExecutor();
launcher.setTaskExecutor(simpleAsyncTaskExecutor);
return launcher;
}
正如您在问题中所说的那样,您正在使用Oracle数据库,所以很可能您不需要ResourcelessTransactionManager
。
您当前的代码正在做的是将作业元数据存储到基于内存结构的地图中,我的猜测是您不会在生产中执行此操作而您实际上将作业元数据存储在数据库中 - 以供以后分析,重启能力等等
在Spring Batch中,有两种事务 - 一种用于业务数据和方法,另一种用于作业存储库,并且假设您想要从文件读取,写入文件并希望将作业元数据存储到MapJobRepository
然后您的代码会好起来的。
但是你定义一个DataSource
的那一刻,你就不能使用ResourcelessTransactionManager
。事实上,对于数据库,您不需要自己定义任何事务管理器,但Spring Batch面向块的处理将自行处理并将作业元数据存储到数据库中。