标签: spring-batch

为什么Spring的jdbcTemplate.batchUpdate()这么慢?

我正在尝试找到更快的批量插入方法.

我试图用jdbcTemplate.update(String sql)插入几个批处理,其中sql是由StringBuilder 构建的,如下所示:

INSERT INTO TABLE(x, y, i) VALUES(1,2,3), (1,2,3), ... , (1,2,3)
Run Code Online (Sandbox Code Playgroud)

批量大小正好是1000.我插入了近100批.我使用StopWatch检查了时间并找出了插入时间:

min[38ms], avg[50ms], max[190ms] per batch
Run Code Online (Sandbox Code Playgroud)

我很高兴,但我想让我的代码变得更好.

之后,我尝试使用jdbcTemplate.batchUpdate,如:

    jdbcTemplate.batchUpdate(sql, new BatchPreparedStatementSetter() {
        @Override
        public void setValues(PreparedStatement ps, int i) throws SQLException {
                       // ...
        }
        @Override
        public int getBatchSize() {
            return 1000;
        }
    });
Run Code Online (Sandbox Code Playgroud)

sql的样子

INSERT INTO TABLE(x, y, i) VALUES(1,2,3);
Run Code Online (Sandbox Code Playgroud)

我很失望!jdbcTemplate以分开的方式执行1000行批处理的每个插入.我在mysql_log上找到了,发现有一千个插入.我使用StopWatch检查了时间并找出了插入时间:

min [900ms],avg [1100ms],每批最大[2000ms]

那么,任何人都可以向我解释一下,为什么jdbcTemplate在这个方法中做了单独的插入?为什么方法的名称是batchUpdate?或者可能是我以错误的方式使用这种方法?

java mysql spring jdbctemplate spring-batch

21
推荐指数
7
解决办法
6万
查看次数

Spring Batch Framework - 自动创建批处理表

我刚刚使用Spring Batch框架创建了一个批处理作业,但是我没有运行CREATE SQL的数据库权限.当我尝试运行批处理作业时,我在框架尝试创建TABLE_BATCH_INSTANCE时遇到错误.我试着禁用

<jdbc:initialize-database data-source="dataSource" enabled="false">    
 ...
</jdbc:initialize-database>
Run Code Online (Sandbox Code Playgroud)

但在我尝试之后我仍然遇到了错误

org.springframework.jdbc.BadSqlGrammarException: PreparedStatementCallback; bad SQL grammar [SELECT JOB_INSTANCE_ID, JOB_NAME from BATCH_JOB_INSTANCE where JOB_NAME = ? and JOB_KEY = ?]; nested exception is java.sql.SQLSyntaxErrorException: ORA-00942: table or view does not exist
Run Code Online (Sandbox Code Playgroud)

无论如何可以禁用SQL,我只想测试我的读写器和处理器正常工作.

database privileges spring ora-00942 spring-batch

21
推荐指数
5
解决办法
4万
查看次数

BeanDefinitionParsingException:配置:元素[step2]无法访问

我有类似这个的春季批处理工作:

<batch:job id="job">
    <batch:step id="step1">
        ...
    </batch:step>
    <batch:step id="step2">
        ...
    </batch:step>
</batch:job>
Run Code Online (Sandbox Code Playgroud)

当我试图执行我得到的工作

BeanDefinitionParsingException: Configuration problem: The element [step2] is unreachable
Run Code Online (Sandbox Code Playgroud)

spring spring-batch

20
推荐指数
1
解决办法
6681
查看次数

Spring Batch:一个阅读器,多个处理器和编写器

在Spring批处理中,我需要将ItemReader读取的项目传递给两个不同的处理器和编写器.我想要实现的是......

                        +---> ItemProcessor#1 ---> ItemWriter#1
                        |
ItemReader ---> item ---+
                        |
                        +---> ItemProcessor#2 ---> ItemWriter#2

这是必要的,因为通过ItemWriter#1写入项目应在一个完全不同的方式来处理与通过ItemWriter#2写入的那些.此外,ItemReader从数据库中读取项目,并且它执行的查询计算成本很高,因此应该丢弃执行两次相同的查询.

有关如何实现此类设置的任何提示?或者,至少,逻辑上等同的设置?

spring spring-batch itemwriter itemprocessor

19
推荐指数
2
解决办法
3万
查看次数

Spring Batch ORA-08177:在运行单个作业SERIALIZED隔离级别时无法序列化此事务的访问权限

我在Spring Batch中的JobRepository上使用SERIALIZED隔离级别获取此异常:

org.springframework.dao.CannotSerializeTransactionException: PreparedStatementCallback; SQL [INSERT into DATAFEED_APP.BATCH_JOB_INSTANCE(JOB_INSTANCE_ID, JOB_NAME, JOB_KEY, VERSION) values (?, ?, ?, ?)]; ORA-08177: can't serialize access for this transaction
Run Code Online (Sandbox Code Playgroud)

; 嵌套异常是java.sql.SQLException:ORA-08177:无法序列化此事务的访问权限

at org.springframework.jdbc.support.SQLErrorCodeSQLExceptionTranslator.doTranslate(SQLErrorCodeSQLExceptionTranslator.java:269)
at org.springframework.jdbc.support.AbstractFallbackSQLExceptionTranslator.translate(AbstractFallbackSQLExceptionTranslator.java:72)
at org.springframework.jdbc.core.JdbcTemplate.execute(JdbcTemplate.java:603)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:812)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:868)
at org.springframework.jdbc.core.JdbcTemplate.update(JdbcTemplate.java:872)
at org.springframework.batch.core.repository.dao.JdbcJobInstanceDao.createJobInstance(JdbcJobInstanceDao.java:105)
at org.springframework.batch.core.repository.support.SimpleJobRepository.createJobExecution(SimpleJobRepository.java:135)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597)
at org.springframework.aop.support.AopUtils.invokeJoinpointUsingReflection(AopUtils.java:317)
at org.springframework.aop.framework.ReflectiveMethodInvocation.invokeJoinpoint(ReflectiveMethodInvocation.java:183)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:150)
at org.springframework.transaction.interceptor.TransactionInterceptor.invoke(TransactionInterceptor.java:110)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.batch.core.repository.support.AbstractJobRepositoryFactoryBean$1.invoke(AbstractJobRepositoryFactoryBean.java:172)
at org.springframework.aop.framework.ReflectiveMethodInvocation.proceed(ReflectiveMethodInvocation.java:172)
at org.springframework.aop.framework.JdkDynamicAopProxy.invoke(JdkDynamicAopProxy.java:204)
at $Proxy27.createJobExecution(Unknown Source)
at org.springframework.batch.core.launch.support.SimpleJobLauncher.run(SimpleJobLauncher.java:124)
at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:39)
at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:25)
at java.lang.reflect.Method.invoke(Method.java:597) …
Run Code Online (Sandbox Code Playgroud)

oracle isolation-level spring-batch

19
推荐指数
4
解决办法
3万
查看次数

如何在SpringBatch中的ItemReader之后处理逻辑上相关的行?

脚本

为简单起见,假设我有一个ItemReader,它返回25行.

  1. 前10行属于学生A.

  2. 接下来的5个属于学生B.

  3. 剩下的10个属于学生C.

我想通过studentId合理地将它们聚合在一起并将它们展平,最终每个学生一行.

问题

如果我理解正确,将提交间隔设置为5将执行以下操作:

  1. 向处理器发送5行(将汇总它们或执行我告诉它的任何业务逻辑).
  2. 在Processed之后将写入5行.
  3. 然后它将在接下来的5行中再次执行它,依此类推.

如果这是真的,那么对于接下来的五个,我将不得不检查已经写好的那些,将它们聚合到我正在处理的那些并再次写入它们.

我个人不这样做.

  1. 在Spring Batch中处理这种情况的最佳实践是什么?

替代

有时我觉得编写一个常规的Spring JDBC主程序要容易得多,然后我就可以完全控制自己想要做的事情了.但是,我想利用作业存储库状态监视作业,重启,跳过,作业和步骤监听器的能力....

我的春季批次代码

我的module-context.xml

   <?xml version="1.0" encoding="UTF-8"?>
<beans xmlns="http://www.springframework.org/schema/beans"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xmlns:batch="http://www.springframework.org/schema/batch"
    xsi:schemaLocation="http://www.springframework.org/schema/batch http://www.springframework.org/schema/batch/spring-batch-2.1.xsd
    http://www.springframework.org/schema/beans http://www.springframework.org/schema/beans/spring-beans-3.0.xsd">

    <description>Example job to get you started. It provides a skeleton for a typical batch application.</description>

    <batch:job id="job1">
        <batch:step id="step1"  >           
            <batch:tasklet transaction-manager="transactionManager" start-limit="100" >             
                 <batch:chunk reader="attendanceItemReader"
                              processor="attendanceProcessor" 
                              writer="attendanceItemWriter" 
                              commit-interval="10" 
                 />

            </batch:tasklet>
        </batch:step>
    </batch:job> 

    <bean id="attendanceItemReader" class="org.springframework.batch.item.database.JdbcCursorItemReader"> 
        <property name="dataSource">
            <ref bean="sourceDataSource"/>
        </property> 
        <property name="sql"                                                    
                  value="select s.student_name …
Run Code Online (Sandbox Code Playgroud)

spring-batch

18
推荐指数
2
解决办法
2万
查看次数

如何在ItemWriter中获取JobParameter和JobExecutionContext?

我想在班上检索JobParameterJobExecutionContext反对ItemWriter.如何进行?

我尝试实现StepExecutionListener,我只是调用父类方法.但它没有取得成功.

提前致谢.

spring-batch

18
推荐指数
4
解决办法
6万
查看次数

Spring Batch:org.springframework.batch.item.ReaderNotOpenException:Reader必须先打开才能读取

我阅读了相关问题,但解决方案对我不起作用.

我得到了org.springframework.batch.item.ReaderNotOpenException: Reader must be open before it can be read例外.

以下是我的配置:

@Bean
@StepScope
public ItemReader<Player> reader(@Value("#{jobParameters[inputZipfile]}") String inputZipfile) {
                final String [] header = { .. this part omitted for brevity ... };
                FlatFileItemReader<Player> reader = new FlatFileItemReader<Player>();


                System.out.println("\t\t\t\t\t"+inputZipfile);

                reader.setResource(new ClassPathResource(inputZipfile));
                reader.setLineMapper(new DefaultLineMapper<Player>() {{
                    setLineTokenizer(new DelimitedLineTokenizer() {{
                        setNames( header );
                    }});
                    setFieldSetMapper(new BeanWrapperFieldSetMapper<Player>() {{
                        setTargetType(Player.class);
                    }});
                }});
                reader.setComments( header );
                return reader;
}

@Bean
@StepScope
public ItemProcessor<Player, PlayersStats> processor(@Value("#{jobParameters[statType]}") String statType,
                                                                 @Value("#{jobParameters[season]}") String season){
                PlayersStatsProcessor psp = …
Run Code Online (Sandbox Code Playgroud)

java spring-batch

18
推荐指数
3
解决办法
1万
查看次数

需要了解spring.handlers和spring.schemas

我有一些问题来自我已经通过另一个问题解决的问题.但是,我仍然想知道根本原因.我的问题如下:

  1. spring.handlersspring.schemas的目的是什么?

据我所知,这是一种告诉Spring Framework在哪里找到xsd以便所有内容都正确连线和加载的方法.但...

  1. 在什么情况下我应该在META-INF文件夹下有这两个文件?

  2. 在我上面链接的另一个问题中,是否有人知道为什么我必须maven-shade-plugin在META-INF下添加创建这两个文件(基于我所有的依赖项)?换句话说,导致我必须使用maven shade插件的根本原因是什么?

spring xsd uri spring-batch spring-3

17
推荐指数
1
解决办法
2万
查看次数

Spring批处理步骤范围如何工作

我有一个要求,我需要根据其中我得到文件名的其余调用来处理文件,我将它添加到job参数并在创建bean时使用它.

我正在为(读者,作家)和使用job参数创建步骤范围Bean.我正在一个新线程中开始工作,因为我使用异步任务exceutor来启动工作,我的问题是如何通过spring创建bean当我们定义 @StepScope

jobParametersBuilder.addString("fileName", request.getFileName());
jobExecution = jobLauncher.run(job, jobParametersBuilder.toJobParameters());
@Bean
public JobLauncher jobLauncher() {
    SimpleJobLauncher jobLauncher = new SimpleJobLauncher();
    jobLauncher.setJobRepository(jobRepository());
    jobLauncher.setTaskExecutor(asyncTaskExecutor());
    return jobLauncher;
}

@Bean
@StepScope
public ItemWriter<Object> writer(@Value ("#{jobParameters['fileName']}"String    fileName) {
    JdbcBatchItemWriter<Object> writer = new JdbcBatchItemWriter<>();
    writer.setItemSqlParameterSourceProvider(
        new BeanPropertyItemSqlParameterSourceProvider<Object>());
    writer.setSql(queryCollection.getquery());
    writer.setDataSource(dataSource(fileName));
    return writer;
}
Run Code Online (Sandbox Code Playgroud)

spring spring-batch

17
推荐指数
1
解决办法
2万
查看次数