SpringBatch从入门到精通-5 数据源配置相关

1.配置数据源

1.1 配置mybaits

添加pom

   <dependency>
       <groupId>org.mybatis.spring.boot</groupId>
       <artifactId>mybatis-spring-boot-starter</artifactId>
       <version>1.3.2</version>
   </dependency>

配置文件增加内容:

# mybatis
mybatis.mapper-locations=classpath:mapper/*Mapper.xml

增加包扫描

@MapperScan("com.jackssybin.demo03.mapper")

2.配置JobRepository

使用时

@EnableBatchProcessing

JobRepository

为您提供开箱即用的一个。本节介绍如何配置您自己的。


JobRepository用于 Spring Batch 中各种持久域对象的基本 CRUD 操作,例如

JobExecution

StepExecution

。许多主要框架功能都需要它,例如

JobLauncher

Job

Step

.


使用 java 配置时,

JobRepository

为您提供了一个,则提供了一个基于 JDBC 的开箱即用,如果没有

DataSource

提供,则提供基于 JDBC 的

Map

。但是,您可以

JobRepository

通过接口的实现来自 定义配置

BatchConfigurer


@Override
protected JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.setIsolationLevelForCreate("ISOLATION_SERIALIZABLE");
    factory.setTablePrefix("BATCH_");
    factory.setMaxVarCharLength(1000);
    return factory.getObject();

除了 dataSource 和 transactionManager 之外,上面列出的配置选项都不是必需的。如果未设置,将使用上面显示的默认值。

setIsolationLevelForCreate:创建的隔离级别默认是序列化

setTablePrefix:表名前缀默认是BATCH_

setMaxVarCharLength:默认最大长度是1000

2.1 配置事务(隔离级别等)

方法属性中的隔离级别

create*

是单独指定的,以确保在启动作业时,如果两个进程尝试同时启动同一个作业,则只有一个成功。该方法的默认隔离级别是

SERIALIZABLE

,这是非常激进的。

READ_COMMITTED

也可以。

READ_UNCOMMITTED

如果两个进程不太可能以这种方式发生冲突,那就没问题了。然而,由于调用

create*

方法很短,不太可能

SERIALIZED

出问题,只要数据库平台支持。但是,这可以被覆盖。


@Override
protected JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.setIsolationLevelForCreate("ISOLATION_REPEATABLE_READ");
    return factory.getObject();

如果不使用命名空间或工厂 bean,那么使用 AOP 配置存储库的事务行为也很重要。

使用TransactionProxyFactoryBean 事务代理工厂类为事务进行增强:

@Bean
public TransactionProxyFactoryBean baseProxy() {
    TransactionProxyFactoryBean transactionProxyFactoryBean = new TransactionProxyFactoryBean();
    Properties transactionAttributes = new Properties();
    transactionAttributes.setProperty("*", "PROPAGATION_REQUIRED"); //配置全局的传播行为
    transactionProxyFactoryBean.setTransactionAttributes(transactionAttributes);
    transactionProxyFactoryBean.setTarget(jobRepository());
    transactionProxyFactoryBean.setTransactionManager(transactionManager());
    return transactionProxyFactoryBean;

事务的默认行为: AbstractJobRepositoryFactoryBean#initializeProxy()

TransactionInterceptor advice = new TransactionInterceptor(transactionManager,
                    PropertiesConverter.stringToProperties("create*=PROPAGATION_REQUIRES_NEW,"
                            + isolationLevelForCreate + "\ngetLastJobExecution*=PROPAGATION_REQUIRES_NEW,"
                            + isolationLevelForCreate + "\n*=PROPAGATION_REQUIRED"));

解释: create* 开头的方法都使用PROPAGATION_REQUIRES_NEW 级别。都是新事物,隔离级别是传进来的isolationLevelForCreate

getLastJobExecution* 也是PROPAGATION_REQUIRES_NEW 级别,隔离级别是传进来的isolationLevelForCreate。

2.2 更改表前缀

另一个可修改的属性

JobRepository

是元数据表的表前缀。默认情况下,它们都以

BATCH_

.

BATCH_JOB_EXECUTION

并且

BATCH_STEP_EXECUTION

是两个例子。但是,有可能修改此前缀的原因。如果模式名称需要添加到表名称之前,或者如果同一模式中需要多组元数据表,则需要更改表前缀:


@Override
protected JobRepository createJobRepository() throws Exception {
    JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean();
    factory.setDataSource(dataSource);
    factory.setTransactionManager(transactionManager);
    factory.setTablePrefix("SYSTEM.TEST_");
    return factory.getObject();

对元数据表的每个查询都带有前缀

SYSTEM.TEST_

BATCH_JOB_EXECUTION

被称为系统。TEST_JOB_EXECUTION为更改之后的表


ps(只有表前缀是可配置的。表名和列名不是。)

也可以在配置文件中进行配置

spring.batch.table-prefix=batch_

2.3 内存数据库

在某些情况下,您可能不想将域对象持久化到数据库中。一个原因可能是速度。在每个提交点存储域对象需要额外的时间。另一个原因可能是您不需要为特定工作保留状态。出于这个原因,Spring 批处理提供了

Map

作业存储库的内存版本。


以下示例显示了

MapJobRepositoryFactoryBean

Java 中的包含:


@Override
protected JobRepository createJobRepository() throws Exception {
    MapJobRepositoryFactoryBean factory = new MapJobRepositoryFactoryBean();
    factory.setTransactionManager(transactionManager);
    return factory.getObject();

请注意,内存存储库是易丢失的,因此不允许在 JVM 实例之间重新启动。它也不能保证两个具有相同参数的作业实例同时启动,并且 不适合 在多线程作业或本地分区的作业中使用

Step

。因此,只要您需要这些功能,就可以使用存储库的数据库版本。


然而,它确实需要定义事务管理器,因为存储库中有回滚语义,并且因为业务逻辑可能仍然是事务性的(例如 RDBMS 访问)。出于测试目的,许多人发现它

ResourcelessTransactionManager

很有用。


相关的

MapJobRepositoryFactoryBean

类在 v4 中已被弃用,并计划在 v5 中删除。如果要使用内存中的作业存储库,可以使用嵌入式数据库,如 H2、Apache Derby 或 HSQLDB。有几种方法可以创建嵌入式数据库并在 Spring Batch 应用程序中使用它。一种方法是使用


Spring JDBC中的 API :

@Bean
public DataSource dataSource() {
    return new EmbeddedDatabaseBuilder()
            .setType(EmbeddedDatabaseType.H2)
            .addScript("/org/springframework/batch/core/schema-drop-h2.sql")
            .addScript("/org/springframework/batch/core/schema-h2.sql")
            .build();

在应用程序上下文中将嵌入式数据源定义为 bean 后,如果使用

@EnableBatchProcessing

. 否则,您可以使用基于 JDBC 的手动配置它

JobRepositoryFactoryBean

.


  • 添加内存数据库H2:
  • pom添加
<!-- https://mvnrepository.com/artifact/com.h2database/h2 -->
<dependency>
    <groupId>com.h2database</groupId>
    <artifactId>h2</artifactId>
    <version>1.4.200</version>
</dependency>

也可以在配置文件进行配置:

# Enabling H2 Console
spring.h2.console.enabled=true