2014-08-28 8 views
20

में एकाधिक डेटा स्रोतों का उपयोग मैं स्प्रिंग बैच के भीतर कुछ डेटा स्रोतों को कॉन्फ़िगर करने की कोशिश कर रहा हूं। स्टार्टअप पर, स्प्रिंग बैच निम्न अपवाद फेंक है:स्प्रिंग बैच

To use the default BatchConfigurer the context must contain no more thanone DataSource, found 2

बैच विन्यास से स्निपेट

@Configuration 
@EnableBatchProcessing 
public class BatchJobConfiguration { 

    @Primary 
    @Bean(name = "baseDatasource") 
    public DataSource dataSource() { 
     // first datasource definition here 
    } 
    @Bean(name = "secondaryDataSource") 
    public DataSource dataSource2() { 
     // second datasource definition here 
    } 
    ... 
} 

सुनिश्चित नहीं हैं कि क्यों मैं इस अपवाद देख रहा हूँ, क्योंकि मैं के लिए कुछ एक्सएमएल आधारित विन्यास देखा है वसंत बैच जो एकाधिक डेटा स्रोत घोषित करता है। मैं वसंत बूट संस्करण 1.1.5.RELEASE के साथ स्प्रिंग बैच कोर संस्करण 3.0.1.RELEASE का उपयोग कर रहा हूँ। किसी भी तरह की सहायता का स्वागत किया जाएगा।

+2

एक्सएमएल के साथ आपको स्पष्ट होना चाहिए कि स्प्रिंग बैच किस डेटास्रोत का उपयोग करता है। यदि आप इसे जावा आधारित कॉन्फ़िगरेशन के साथ स्पष्ट रूप से घोषित नहीं करते हैं तो यह डेटासोर्स को काम करने का पता लगाने की कोशिश करेगा, जो केवल एक ही डेटासोर्स का पता लगाए जाने पर ही काम करेगा। आप 'प्राथमिक' के साथ बैच के लिए उपयोग करने के लिए एक को एनोटेट करने का प्रयास कर सकते हैं। अन्यथा आप 'डिफॉल्टबैच कॉन्फ़िगरर' बना सकते हैं जिसके लिए एक डेटासोर्स को निर्माण तर्क के रूप में आवश्यक है और इसे उपयोग करने के लिए पास करें। –

+2

मैंने @ प्राथमिक के साथ प्रयास किया है और यह काम नहीं करता है, मैं डिफ़ॉल्ट बैच कॉन्फ़िगरर के साथ प्रयास करूंगा। –

+0

यह दृष्टिकोण कुछ हद तक सहायक है http://stackoverflow.com/a/25811665/701368 – wmarbut

उत्तर

13

AbstractBatchConfiguration देखने के लिए कंटेनर में BatchConfigurer पहले, अगर यह तो नहीं मिला वह खुद को बनाने की कोशिश कर रहा है की कोशिश करता है - यह वह जगह है जहाँ कंटेनर में एक से अधिक DataSource सेम है जहां IllegalStateException फेंक दिया है।

समस्या को हल करने का दृष्टिकोण DefaultBatchConfigurer बीन AbstractBatchConfiguration में बीन से रोकने के लिए है। यह ऐसा करने के लिए हम @Component एनोटेशन का उपयोग कर स्प्रिंग कंटेनर द्वारा DefaultBatchConfigurer बनाने के लिए संकेत:

विन्यास वर्ग जहां @EnableBatchProcessing हम @ComponentScan कि पैकेज है कि खाली वर्ग DefaultBatchConfigurer से ली गई है जिसमें स्कैन के साथ टिप्पणी कर सकते हैं रख दिया गया है:

package batch_config; 
... 
@EnableBatchProcessing 
@ComponentScan(basePackageClasses = MyBatchConfigurer.class) 
public class MyBatchConfig { 
    ... 
} 

कि खाली व्युत्पन्न वर्ग से भरा कोड यहाँ है:

package batch_config.components; 
import org.springframework.batch.core.configuration.annotation.DefaultBatchConfigurer; 
import org.springframework.stereotype.Component; 
@Component 
public class MyBatchConfigurer extends DefaultBatchConfigurer { 
} 

इस विन्यास में @Primary एनोटेशन नीचे दिए गए उदाहरण में के रूप में DataSource सेम के लिए काम करता है:

@Configuration 
public class BatchTestDatabaseConfig { 
    @Bean 
    @Primary 
    public DataSource dataSource() 
    { 
     return .........; 
    } 
} 

यह वसंत बैच संस्करण 3.0.3.RELEASE

सरल समाधान के लिए काम करता है DataSource काम पर @Primary एनोटेशन बनाने के लिए शायद @EnableBatchProcessing एनोटेशन के साथ जोड़ रहा हो सकता है:

@Configuration 
@EnableBatchProcessing 
@ComponentScan(basePackageClasses = DefaultBatchConfigurer.class) 
public class MyBatchConfig { 
+0

यह दृष्टिकोण अच्छी तरह से काम करता है। –

0

सबसे पहले, एक कस्टम BatchConfigurer

@Configuration 
@Component 
public class TwoDataSourcesBatchConfigurer implements BatchConfigurer { 

    @Autowired 
    @Qualifier("dataSource1") 
    DataSource dataSource; 

    @Override 
    public JobExplorer getJobExplorer() throws Exception { 
     ... 
    } 

    @Override 
    public JobLauncher getJobLauncher() throws Exception { 
     ... 
    } 

    @Override 
    public JobRepository getJobRepository() throws Exception { 
     JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); 
     // use the autowired data source 
     factory.setDataSource(dataSource); 
     factory.setTransactionManager(getTransactionManager()); 
     factory.afterPropertiesSet(); 
     return factory.getObject(); 
    } 

    @Override 
    public PlatformTransactionManager getTransactionManager() throws Exception      { 
     ... 
    } 

} 

फिर,

@Configuration 
@EnableBatchProcessing 
@ComponentScan("package") 
public class JobConfig { 
    // define job, step, ... 
} 
15

आप अपनी खुद की BatchConfigurer प्रदान करनी चाहिए पैदा करते हैं। वसंत के लिए आप

@Configuration 
@EnableBatchProcessing 
public class BatchConfig { 

    @Bean 
     BatchConfigurer configurer(@Qualifier("batchDataSource") DataSource dataSource){ 
     return new DefaultBatchConfigurer(dataSource); 
     } 

... 
+0

यह एक आकर्षण की तरह काम कर रहा है। – jalpa

+0

सरल और प्रभावी। धन्यवाद! –

0

कि फैसला लेने के लिए मैं ऊपर सवाल का जोड़ सकते हैं नहीं चाहता है, 2 लेन-देन होने के निहितार्थ प्रत्येक डी एस के लिए एक संदर्भों। बैच चरण के साथ एक्सए लेनदेन को एकीकृत कैसे करें क्योंकि हमें चरण स्तर पर TXN प्रबंधन सुनिश्चित करना होगा? आवश्यकता एक बैच चरण में है जैसे हमें निम्नलिखित की आवश्यकता है।jpaItemReader DS2 को

  • लिखने - - डी एस 1 से

    1. पढ़ने JPAItemwriter
    2. DS2 से पढ़ा - JPAItemreader
    3. DS1 को लिखने - JPAItemwriter
    4. सभी txns चरण पूरा कर लिया प्रतिबद्ध होते हैं।
  • +0

    इतना आसान नहीं है। इस जॉब कॉन्फ़िगरर (जिसे आपने बताया है) के साथ बनाए गए बैच चरण एक डीएस होंगे। और एक टीएक्सएन प्रबंधक। लेकिन रेक यह है कि एक ही चरण में 2 अलग-अलग डीएस होना चाहिए जो पढ़ा और लिखा जाएगा। और उनमें से प्रत्येक के पास अलग-अलग TxnManager होगा जो एक चेन किए गए TXN प्रबंधक द्वारा बंधे हैं या एक एक्सए TXN प्रबंधक है जो अंत में किए गए सभी इकाइयों को सुनिश्चित करेगा। – saiD

    +0

    @imarchuang - आप काफी सही हैं। लेकिन मेरी आवश्यकता में एक और महत्वपूर्ण बिंदु का उल्लेख किया गया था, यानी अलग-अलग डीएस के लिए अलग-अलग लेनदेन प्रबंधक का उपयोग एकल बैच चरण के संलग्न संदर्भ को ध्यान में रखते हुए। इसके लिए मैंने ChainedTransactionManager का उपयोग किया जो बदले में प्रत्येक डीएस के लिए दो अलग प्लेटफॉर्म ट्रांज़ेक्शन प्रबंधक है, और जंजीर TXN प्रबंधक के साथ बैच चरण संलग्न करता है। – saiD

    +0

    और डीएस में से किसी भी को बैच के लिए एम्बेडेड डीबी रखने के लिए इस्तेमाल किया जा सकता है। लेकिन जो भी इस्तेमाल किया जाता है उसे प्राथमिक बनाना होता है और डिफ़ॉल्ट स्प्रिंग बैच कॉन्फ़िगरर/कस्टम बैच कॉन्फ़िगरर के साथ वायर्ड किया जाएगा। – saiD

    0

    मैं यहां एक समाधान प्रदान करना चाहता हूं, जो @vanarchi द्वारा उत्तर दिए गए एक जैसा ही है, लेकिन मैं सभी आवश्यक विन्यास एक वर्ग में डाल पाया।

    पूर्णता के लिए, यहां समाधान यह मानता है कि प्राथमिक डेटास्रोत एचएसक्यूएल है।

    @Configuration 
    @EnableBatchProcessing 
    public class BatchConfiguration extends DefaultBatchConfigurer { 
    
    @Bean 
    @Primary 
    public DataSource batchDataSource() { 
    
        // no need shutdown, EmbeddedDatabaseFactoryBean will take care of this 
        EmbeddedDatabaseBuilder builder = new EmbeddedDatabaseBuilder(); 
        EmbeddedDatabase embeddedDatabase = builder 
          .addScript("classpath:org/springframework/batch/core/schema-drop-hsqldb.sql") 
          .addScript("classpath:org/springframework/batch/core/schema-hsqldb.sql") 
          .setType(EmbeddedDatabaseType.HSQL) //.H2 or .DERBY 
          .build(); 
        return embeddedDatabase; 
    } 
    
    @Override 
    protected JobRepository createJobRepository() throws Exception { 
        JobRepositoryFactoryBean factory = new JobRepositoryFactoryBean(); 
        factory.setDataSource(batchDataSource()); 
        factory.setTransactionManager(transactionManager()); 
        factory.afterPropertiesSet(); 
    
        return (JobRepository) factory.getObject(); 
    } 
    
    private ResourcelessTransactionManager transactionManager() { 
        return new ResourcelessTransactionManager(); 
    } 
    
    //NOTE: the code below is just to provide developer an easy way to access the in-momery hsql datasource, as we configured it to the primary datasource to store batch job related data. Default username : sa, password : '' 
    @PostConstruct 
    public void getDbManager(){ 
        DatabaseManagerSwing.main(
          new String[] { "--url", "jdbc:hsqldb:mem:testdb", "--user", "sa", "--password", ""}); 
    } 
    

    }

    तीन इस समाधान में महत्वपूर्ण बिंदुओं:

    1. इस वर्ग @EnableBatchProcessing और @Configuration साथ टिप्पणी की जाती है, साथ ही DefaultBatchConfigurer से बढ़ाया। ऐसा करने से, हम AbstractBatchConfiguration को BatchConfigurer देखने की कोशिश करते समय हमारे अनुकूलित बैच कॉन्फ़िगरर का उपयोग करने के लिए वसंत-बैच को निर्देश देते हैं;
    2. @Primary के रूप में बैचडेटासोर्स बीन एनोटेट करें, जो इस डेटासोर्स का उपयोग 9 नौकरी से संबंधित तालिकाओं को संग्रहीत करने के अपने डेटासोर्स के रूप में करने के लिए वसंत-बैच को निर्देशित करता है।
    3. protected JobRepository createJobRepository() throws Exception विधि ओवरराइड करें, जो प्राथमिक डेटासोर्स का उपयोग करने के लिए जॉब रिपोजिटरी बीन बनाता है, साथ ही साथ अन्य डेटासोर्स से भिन्न लेन-देन प्रबंधक उदाहरण का उपयोग करता है।
    संबंधित मुद्दे