2011-03-07 3 views
2

스프링의 SimpleAsyncTaskExecutor와 함께 Spring JdbcTemplate을 사용하여 DB 에 대한 동시 연결을 만들 수 있으며 단일 스레드 환경에 비해 전체 데이터를 관련 테이블에 짧은 시간에 삽입 할 수 있습니다.다중 스레드 환경에서 JdbcTemplate을 사용하는 방법은 무엇입니까?

다음 코드를 사용하고 있지만 응용 프로그램 속도가 향상되지 않습니다.

내가 찾을 수있는 유일한 단서는 "campaignProductDBWriter"빈은 한 번만 생성되는 반면, 나는 10 개의 별도 인스턴스가 tasklet에 "throttle-limit"을 설정하면 으로 생성 될 것으로 예상하고 있습니다.

내가 뭘 잘못하고 있니? 어떤 도움이나 제안이라도 대단히 감사하겠습니다.

이 당신의 봄 설정 문제가 아닙니다
<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

+0

@skaffman "사양에는 변함이 없습니다. 예를 들어, 동일한 Connection에있는 두 개의 Statement는 동시에 실행될 수 있으며 ResultSet은 동시에 처리 될 수 있습니다 (일부 드라이버는이 완전한 동시성을 제공 할 것이며, 다른 드라이버는 하나의 명령문을 실행하고 완료 될 때까지 기다렸다가 다음 명령문을 전송할 수 있습니다. " 스레드 안전은 9i 용 Oracle OCI의 새로운 기능이라는 것을 알고 있습니다. 그래서 당신이 스레드 안전해야한다는 것이 맞다고 생각합니다. 그러나 모든 것이 동시에 유용하다는 것은 아닙니다. – mezmo

답변

6

, 또는 당신은 JDBC API를 주위에 얇은 상태 비 래퍼 단지 인 jdbcTemplate를 사용하는 방법에

감사합니다.

가장 확실한 가능성은 병목 현상이 데이터베이스가 아닌 코드라는 것입니다. 데이터베이스에 대해 여러 동시 작업을 실행하는 것이 한 번에 하나씩 수행하는 것보다 빠르지 않을 수 있습니다.

데이터베이스 잠금 또는 원시 I/O 성능 부족과 같은 여러 가지 이유가있을 수 있습니다.

성능 향상을 위해 멀티 스레딩을 사용할 때는 병목 현상이 어디에 있는지 확인해야합니다. 코드에 병목 현상이 없다면 다중 스레드로 만드는 것이 더 빨리 작업을 수행하지는 못합니다.

+0

답장을 보내 주셔서 감사합니다. 그러나 저는 왜 bean campaignProductDBWriter가 한 번만 생성되었는지에 대해 궁금합니다. 반면에 10 가지 인스턴스가 생성 될 것으로 기대하고 있습니다. 나는 뭔가를 놓친 것 같아. – Kivanc

1

스프링의 컨텍스트가 초기화되면 컨텍스트에 선언 된 모든 인스턴스가 만들어집니다. <bean id="campaignProductDBWriter" class="com.falcon.cc.job.step.CampaignProductWriter"> <property name="jdbcTemplate" ref="jdbcTemplateProduct" /> </bean>이 코드는 봄에 singleton이 될 CampaignProductWriter의 인스턴스를 생성합니다 (기본적으로 범위는 싱글 톤 임). 빈의 새 인스턴스를 가지려면 해당 범위가 프로토 타입이어야합니다.