2011-03-07 99 views
2

我试图使用Spring的JdbcTemplate使用Spring的SimpleAsyncTaskExecutor这样对DB 并发连接,可以制备和整个数据可以被插入到相关表中的时间量较小时,相比于单线程环境。如何在多线程环境中使用JdbcTemplate?

我用下面的代码,但它不加快我的申请。

我能找到的唯一线索是bean“campaignProductDBWriter”只构造一次,而我期望创建10个独立实例 ,因为我在tasklet中将“throttle-limit”设置为10。

我在做什么错?任何帮助或建议将不胜感激。

问候,

<bean id="dataSourceProduct" 
    class="org.springframework.jdbc.datasource.DriverManagerDataSource" 
    p:driverClassName="${jdbc.driverClassName}" p:url="${jdbc.url.product}" 
    p:username="${jdbc.username.product}" p:password="${jdbc.password.product}" 
/> 

<bean id="jdbcTemplateProduct" class="org.springframework.jdbc.core.JdbcTemplate"> 
    <property name="dataSource" ref="dataSourceProduct" /> 
</bean> 

<bean id="simpleTaskExecutor" class="org.springframework.core.task.SimpleAsyncTaskExecutor" > 
    <property name="concurrencyLimit" value="-1" /> 
</bean> 

<batch:job id="sampleJob" restartable="true" incrementer="dynamicJobParameters">    
    <batch:step id="mapMZList"> 
    <batch:tasklet allow-start-if-complete="true" task-executor="simpleTaskExecutor" throttle-limit="10">      
     <batch:chunk reader="campaignProductItemReader" processor="campaignProductProcessor" writer="campaignProductDBWriter" commit-interval="5000"/>   
    </batch:tasklet> 
    </batch:step>     
</batch:job> 

<bean id="campaignProductDBWriter" class="com.falcon.cc.job.step.CampaignProductWriter"> 
    <property name="jdbcTemplate" ref="jdbcTemplateProduct" /> 
</bean> 


<bean id="campaignProductItemReader" class="com.falcon.cc.job.step.FlatFileSynchronizedItemReader" scope="step">  
    <property name="resource" value="file:#{jobParameters['input.TEST_FILE.path']}"/> 

    <property name="lineMapper"> 
    <bean class="org.springframework.batch.item.file.mapping.DefaultLineMapper">   
     <property name="lineTokenizer">  
     <bean class="org.springframework.batch.item.file.transform.DelimitedLineTokenizer"> 
      <property name="delimiter" value=";"/>    
      <property name="names" value="approvalStatus,validFrom,validTo"/> 
     </bean> 
     </property> 
     <property name="fieldSetMapper"> 
     <bean class="com.falcon.cc.mapper.CampaignProductFieldSetMapper" /> 
     </property> 
    </bean> 
    </property> 
</bean> 
+0

只是一个普遍的观察,许多JDBC驱动程序不是线程安全的,因此为了让10个线程安全地运行,您需要10个连接。你有没有尝试过使用BatchUpdate?虽然我也听说过那里有困难。 – mezmo 2011-03-07 15:16:27

+0

@skaffman“没有变化”即使在规范中,从规范中也不是这样“例如,可以同时执行同一个Connection上的两个语句,并可以同时处理它们的ResultSet(从角度来看开发者),一些驱动程序会提供这种完全并发性,其他驱动程序可能会执行一个语句,并在发送下一个语句之前等待它完成。“我知道线程安全是Oracle OCI for 9i的一项新功能。所以我想你是对的,因为他们应该是线程安全的......但并不是所有的都保证同时有用。 – mezmo 2011-03-08 14:46:00

回答

6

这是不是与你的Spring配置有问题,或者您是如何使用jdbcTemplate,这仅仅是围绕JDBC API薄薄的,无状态的包装。

最明显的可能是你的瓶颈是你的数据库,而不是你的代码。对数据库运行多个并发操作完全有可能比一次只执行一个并发操作更快。

可能有几个方面的原因,如数据库锁定,或者只是缺少原始I/O性能。

当使用多线程来提高性能考虑,你必须确保在您的瓶颈。如果你的代码不是瓶颈,那么使它成为多线程并不会让事情变得更快。

+0

感谢您的回答,但我仍然对bean campaignProductDBWriter为什么只构造一次而感到好奇,但我期望构建10个不同的实例。我想我错过了一些东西。 – Kivanc 2011-03-07 15:15:43

1

春天的背景下被初始化,它会在上下文中声明的所有实例。 <bean id="campaignProductDBWriter" class="com.falcon.cc.job.step.CampaignProductWriter"> <property name="jdbcTemplate" ref="jdbcTemplateProduct" /> </bean>这段代码将导致spring创建一个CampaignProductWriter的实例,它将是一个单例(默认情况下该范围是单例)。 为了有一个新的bean实例,它的范围必须是原型。