2011-03-07 101 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實例,它的範圍必須是原型。