我有Spring Cloud Task,它将数据从SQL Server加载到将在Spring Cloud Data Flow上运行的Cassandra DB。
Spring Task的一个要求是提供关系数据库来保存元数据,如任务执行状态。但我不想使用上述任何一个数据库。相反,我必须为持久性指定第三个数据库。但似乎Spring Cloud Task流程会自动从application.properties中获取SQL Server的数据源属性。如何为任务状态持久性指定另一个数据库?
我的当前属性:
2017-08-31
更新:1 我在下面的代码中添加了指向Michael Minella建议的第3个数据库。现在Spring Task能够连接到这个DB并保持状态。但现在我的批处理作业源查询也连接到此数据库。我改变的只是为任务添加数据源。
spring.datasource.url=jdbc:sqlserver://iphost;databaseName=dbname
spring.datasource.username=user
spring.datasource.password=password
spring.datasource.driverClassName=com.microsoft.sqlserver.jdbc.SQLServerDriver
spring.jpa.show-sql=false
#spring.jpa.hibernate.dialect=org.hibernate.dialect.SQLServer2012Dialect
spring.jpa.hibernate.naming.physical-strategy=org.hibernate.boot.model.naming.PhysicalNamingStrategyStandardImpl
spring.jpa.hibernate.ddl-auto=none
spring.data.cassandra.contact-points=ip
spring.data.cassandra.port=9042
spring.data.cassandra.username=username
spring.data.cassandra.password=password
spring.data.cassandra.keyspace-name=mykeyspace
spring.data.cassandra.schema-action=CREATE_IF_NOT_EXISTS
更新#2:
spring.task.datasource.url=jdbc:postgresql://host:5432/testdb?stringtype=unspecified
spring.task.datasource.username=user
spring.task.datasource.password=passwrod
spring.task.datasource.driverClassName=org.postgresql.Driver
@Configuration
public class DataSourceConfigs {
@Bean(name = "taskDataSource")
@ConfigurationProperties(prefix="spring.task.datasource")
public DataSource getDataSource() {
return DataSourceBuilder.create().build();
}
}
@Configuration
public class DDTaskConfigurer extends DefaultTaskConfigurer{
@Autowired
public DDTaskConfigurer(@Qualifier("taskDataSource") DataSource dataSource) {
super(dataSource);
}
}
更新#3: 如果我为Repository添加配置数据源,我现在得到以下异常。在您提到其中一个数据源需要声明为Primary之前。我已经尝试过了。
@Component
@StepScope
public class MyItemReader extends RepositoryItemReader<Scan> implements InitializingBean{
@Autowired
private ScanRepository repository;
private Integer lastScanIdPulled = null;
public MyItemReader(Integer _lastIdPulled) {
super();
if(_lastIdPulled == null || _lastIdPulled <=0 ){
lastScanIdPulled = 0;
} else {
lastScanIdPulled = _lastIdPulled;
}
}
@PostConstruct
protected void setUpRepo() {
final Map<String, Sort.Direction> sorts = new HashMap<>();
sorts.put("id", Direction.ASC);
this.setRepository(this.repository);
this.setSort(sorts);
this.setMethodName("findByScanGreaterThanId");
List<Object> methodArgs = new ArrayList<Object>();
System.out.println("lastScanIdpulled >>> " + lastScanIdPulled);
if(lastScanIdPulled == null || lastScanIdPulled <=0 ){
lastScanIdPulled = 0;
}
methodArgs.add(lastScanIdPulled);
this.setArguments(methodArgs);
}
}
@Repository
public interface ScanRepository extends JpaRepository<Scan, Integer> {
@Query("...")
Page<Scan> findAllScan(final Pageable pageable);
@Query("...")
Page<Scan> findByScanGreaterThanId(int id, final Pageable pageable);
}
@Configuration
Caused by: java.lang.IllegalStateException: Expected one datasource and found 2
at org.springframework.cloud.task.batch.configuration.TaskBatchAutoConfiguration$TaskBatchExecutionListenerAutoconfiguration.taskBatchExecutionListener(TaskBatchAutoConfiguration.java:65) ~[spring-cloud-task-batch-1.0.3.RELEASE.jar:1.0.3.RELEASE]
at org.springframework.cloud.task.batch.configuration.TaskBatchAutoConfiguration$TaskBatchExecutionListenerAutoconfiguration$$EnhancerBySpringCGLIB$$baeae6b9.CGLIB$taskBatchExecutionListener$0(<generated>) ~[spring-cloud-task-batch-1.0.3.RELEASE.jar:1.0.3.RELEASE]
at org.springframework.cloud.task.batch.configuration.TaskBatchAutoConfiguration$TaskBatchExecutionListenerAutoconfiguration$$EnhancerBySpringCGLIB$$baeae6b9$$FastClassBySpringCGLIB$$5a898c9.invoke(<generated>) ~[spring-cloud-task-batch-1.0.3.RELEASE.jar:1.0.3.RELEASE]
at org.springframework.cglib.proxy.MethodProxy.invokeSuper(MethodProxy.java:228) ~[spring-core-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.context.annotation.ConfigurationClassEnhancer$BeanMethodInterceptor.intercept(ConfigurationClassEnhancer.java:358) ~[spring-context-4.3.14.RELEASE.jar:4.3.14.RELEASE]
at org.springframework.cloud.task.batch.configuration.TaskBatchAutoConfigu
@Configuration
@EnableTransactionManagement
@EnableJpaRepositories(
entityManagerFactoryRef = "myEntityManagerFactory",
basePackages = { "com.company.dd.collector.tool" },
transactionManagerRef = "TransactionManager"
)
public class ToolDbConfig {
@Bean(name = "myEntityManagerFactory")
public LocalContainerEntityManagerFactoryBean
myEntityManagerFactory(
EntityManagerFactoryBuilder builder,
@Qualifier("ToolDataSource") DataSource dataSource
) {
return builder
.dataSource(dataSource)
.packages("com.company.dd.collector.tool")
.persistenceUnit("tooldatasource")
.build();
}
@Bean(name = "myTransactionManager")
public PlatformTransactionManager transactionManager(
@Qualifier("myEntityManagerFactory") EntityManagerFactory
entityManagerFactory
) {
return new JpaTransactionManager(entityManagerFactory);
}
}
答案 0 :(得分:0)
您需要创建TaskConfigurer
以指定要使用的DataSource
。您可以在此处的文档中阅读有关此界面的信息:https://docs.spring.io/spring-cloud-task/1.1.1.RELEASE/reference/htmlsingle/#features-task-configurer
可以在此处找到javadoc:https://docs.spring.io/spring-cloud-task/docs/current/apidocs/org/springframework/cloud/task/configuration/TaskConfigurer.html
更新1:
当使用多个DataSource
时,Spring Batch和Spring Cloud Task都遵循相同的范例,因为它们都有*Configurer
个接口,需要使用它们来指定要使用的DataSource
。对于Spring Batch,您使用BatchConfigurer
(通常只是扩展DefaultBatchConfigurer
),如上所述,TaskConfigurer
用于Spring Cloud Task。这是因为当有多个DataSource
时,框架无法知道使用哪一个。