Spring Cloud Task - 指定数据库配置

标签 spring spring-cloud spring-cloud-task

我有 Spring Cloud Task,它将数据从 SQL Server 加载到将在 Spring Cloud Data Flow 上运行的 Cassandra DB。

Spring Task 的需求之一是提供关系数据库来持久化任务执行状态等元数据。但我不想为此使用上述任何一个数据库。相反,我必须为持久性指定第三个数据库。但似乎 Spring Cloud 任务流会自动从 application.properties 中获取 SQL Server 的数据源属性。如何为任务状态持久性指定另一个数据库?

我的当前属性:

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

更新:1 我按照 Michael Minella 的建议添加了以下代码以指向第三个数据库。现在 Spring Task 能够连接到这个数据库并保持状态。但现在我的批处理作业源查询也连接到这个数据库。我唯一改变的是为任务添加数据源。

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);

    }

}

更新#2:

@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);

}

更新 #3: 如果我为存储库添加配置数据源,我现在会遇到以下异常。在您提到需要将其中一个数据源声明为主要数据源之前。我已经试过了。

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);
      }
}

@配置

public class DataSourceConfigs {


    @Bean(name = "taskDataSource")
    @ConfigurationProperties(prefix="spring.task.datasource")
    public DataSource getDataSource() {
        return DataSourceBuilder.create().build();
    }   

    @Primary
    @Bean(name = "ToolDataSource")
    @ConfigurationProperties(prefix = "tool.datasource")
    public DataSource dataSource() {
      return DataSourceBuilder.create().build();
   }

}

最佳答案

您需要创建一个TaskConfigurer 来指定要使用的DataSource。您可以在此处的文档中阅读有关此接口(interface)的信息: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 接口(interface)需要用来指定什么 DataSource 使用。对于 Spring Batch,您可以使用 BatchConfigurer(通常只需扩展 DefaultBatchConfigurer),如上所述,TaskConfigurer 用于 Spring Cloud Task .这是因为当有多个 DataSource 时,框架无法知道使用哪一个。

关于Spring Cloud Task - 指定数据库配置,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/48674782/

相关文章:

java - 未应用 ActiveMQ 5.7.0 redeliveryPolicy

java - Spring Boot加载程序找不到资源

java - Spring XML 配置 - 如何指定一组对象的属性值?

spring-boot - 使用 Zuul 代理服务器时出现 "Gateway Timeout"错误

java - Spring Cloud DataFlow 组合任务未启动

spring-batch - spring 批处理流作业与 spring 组合任务

java - Mockito - 注入(inject)模拟列表

java - 为什么 com.netflix.spectator.api.Counter 会产生 "normalized"值?

java - 何时使用 org.springframework.context.event.EventListener 和 org.springframework.cloud.stream.annotation.StreamListener

cloud-foundry - 使用 Spring Cloud Task 在启用任务的 Cloud Foundry 上运行任务