2012-05-18 11 views
5

mutliple लेनदेन प्रबंधकों संक्षेपकैसे साथ स्प्रिंग + DBUnit + JUnit

मेरे आदेश पंक्ति जावा अनुप्रयोग प्रतियां डेटा में एक डेटा स्रोत से दूसरे XA का उपयोग किए बिना कॉन्फ़िगर करने के लिए। मैं दो अलग datasources कॉन्फ़िगर किया गया है और एक JUnit परीक्षण है कि दोनों datasources पर डेटा रोलबैक कर सकते हैं करना चाहते हैं। मैं DBUnit का उपयोग "स्रोत" डेटाबेस में डेटा लोड करने के लिए है, लेकिन मैं यह रोलबैक के लिए नहीं मिल सकता है। मैं रोलबैक के लिए "लक्ष्य" डेटासोर्स प्राप्त कर सकता हूं।

मेरे कोड

इस config को देखते हुए ...

<tx:annotation-driven /> 

<!-- note the default transactionManager name on this one --> 
<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource"  ref="dataSourceA" /> 
</bean> 

<bean id="transactionManagerTarget" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource"  ref="dataSourceB" /> 
</bean> 

और इस कोड को ...

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"classpath:resources/spring-context.xml", 
           "classpath:resources/spring-db.xml"}) 
@Transactional 
@TransactionConfiguration(transactionManager = "transactionManagerTarget", defaultRollback = true) 
public class MyIntegrationTest { 

    @Autowired 
    private MyService service; 

    @Autowired 
    @Qualifier("dataSourceA") 
    private DataSource dataSourceA; 

    private IDataSet loadedDataSet; 

    /** 
    * Required by DbUnit 
    */ 
    @Before 
    public void setUp() throws Exception { 
     SybaseInsertIdentityOperation.TRUNCATE_TABLE.execute(getConnection(), getDataSet()); 
     SybaseInsertIdentityOperation.INSERT.execute(getConnection(), getDataSet()); 
    } 

    /** 
    * Required by DbUnit 
    */ 
    protected IDataSet getDataSet() throws Exception { 
     loadedDataSet = DbUnitHelper.getDataSetFromFile(getConnection(), "TestData.xml"); 
     return loadedDataSet; 
    } 

    /** 
    * Required by DbUnit 
    */ 
    protected IDatabaseConnection getConnection() throws Exception{ 
     return new DatabaseConnection(dataSourceA.getConnection()); 
    } 

    @Test 
    public void testSomething() { 

     // service.doCopyStuff(); 

    } 

} 

समस्या मैं इसे देखते हैं, है कि @TransactionConfiguration केवल राज्यों रोलबैक सक्षम करने के लिए लक्षित डेटासॉर। DBUnit dataSourceA स्पष्ट रूप से भेजी जा रही है और डिफ़ॉल्ट लेन-देन प्रबंधक transactionManager नामित जो रोलबैक करने के लिए कहा नहीं किया गया है (मुझे यकीन है कि कैसे नहीं कर रहा हूँ) उठा रहा है।

प्रश्न

कैसे मैं दोनों लेन-देन प्रबंधकों रोलबैक करने के लिए बता सकते हैं?

मैं एक एकल लेनदेन प्रबंधक का उपयोग कर सकते जब मेरे datasources XA लेन-देन का समर्थन नहीं करते?

नोट: उत्पादन में चलते समय एप्लिकेशन को सोर्सए पर लेनदेन प्रबंधक की आवश्यकता नहीं होती है क्योंकि यह केवल पढ़ने के लिए ही होगी। यह मुद्दा केवल मेरे परीक्षण वर्गों के लिए है।

उत्तर

0

एक संभावित समाधान, एक सहायक सेम @Transactional("transactionManagerTarget") के रूप में व्याख्या किए गए परिचय और अपने परीक्षण @Transactional("transactionManager") के रूप में एनोटेट छोड़ देते हैं, defaultRollback = true के साथ दोनों को विन्यस्त करने के लिए किया जाएगा नहीं है। आपका परीक्षण तो सहायक सेम, जो बारी में परीक्षण के अंतर्गत आपकी सेवा सेम कहेंगे फोन करना होगा। इससे आपकी सेवा के आसपास लेन-देन वापस लेना चाहिए, फिर डीबीयूनीट के आसपास लेनदेन करना चाहिए।

हालांकि यह थोड़ा गन्दा है।

अन्य संभावित दृष्टिकोण:

  • एक में स्मृति डेटाबेस का उपयोग करते हुए इस तरह के बजाय एच 2 अपने उत्पादन के रूप में database- आप जरूरत पड़ने पर यह अपने डेटा के सभी ड्रॉप करने के लिए कॉन्फ़िगर कर सकते हैं।
  • डीबीयूनीट को प्रतिबद्ध करने की अनुमति दें, और डेटा को साफ़ करने के लिए अपने आंसू-डाउन विधि में एक क्षतिपूर्ति लेनदेन करें।
+0

मैंने एक सहायक बीन फैक्टरिंग करने की कोशिश की लेकिन यह siutation की मदद नहीं करता है। हुड के नीचे कहीं डीबीयूनीट कई लेनदेन प्रबंधक होने पर रोलबैक नहीं करेगा। मैं आगे बढ़ने के रूप में HSQL का उपयोग करने के लिए अपना उत्तर स्वीकार करने जा रहा हूं, हालांकि मेरे मामले में मैं अभी भी अटक गया हूं क्योंकि मैं इस डेटासोर्स पर एक अस्थायी तालिका बनाने के लिए Sybase का उपयोग करता हूं और वाक्यविन्यास एचएसक्यूएल के साथ संगत नहीं है। – Brad

1

अपने लेनदेन प्रबंधक परिभाषा के अंदर <qualifier> तत्व का उपयोग करें।

<bean id="transactionManager" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSourceA" /> 
    <qualifier value="transactionManager" /> 
</bean> 

<bean id="transactionManagerTarget" class="org.springframework.jdbc.datasource.DataSourceTransactionManager"> 
    <property name="dataSource" ref="dataSourceB" /> 
    <qualifier value="transactionManagerTarget" /> 
</bean> 

तो फिर तुम, संदर्भित कर सकते हैं जो आपके @Transactional एनोटेशन में सीधे उपयोग करना चाहते हैं अर्थात

@RunWith(SpringJUnit4ClassRunner.class) 
@ContextConfiguration(locations={"classpath:resources/spring-context.xml", 
           "classpath:resources/spring-db.xml"}) 
@Transactional("transactionManagerTarget") 
@TransactionConfiguration(defaultRollback = true) 
public class MyIntegrationTest { 
... 
+0

मेरी समझ यह क्यों नहीं काम करेगी कि '@ पहले और '@ टेस्ट' विधियां एक ही लेनदेन में निष्पादित होंगी और मैं एक से अधिक @ ट्रान्सएक्शनल एनोटेशन निर्दिष्ट करने में असमर्थ हूं। आपके उत्तर में, मैं नहीं देख सकता कि यह कैसे 'लेनदेन प्रबंधक' रोलबैक को बताता है। क्या मैं कुछ भूल रहा हूँ? हालांकि ' 'का उपयोग करने पर अच्छा बिंदु। – Brad

+0

मैंने अपनी टेस्ट क्लास पर '@ ट्रांजेक्शनल 'के विभिन्न उपयोगों की कोशिश की लेकिन दुर्भाग्यवश मुझे संदेह था कि' टेस्ट 'विधि लेनदेन शुरू करती है और' @ पहले 'डीबीयूनीट के लिए कोई और शुरू नहीं कर सकता है, इसलिए यह लेनदेन प्रबंधक लक्ष्य के साथ चल रहा है और इसलिए नहीं डीबीयूनीट डेटा रोलबैक। मुझे लगता है कि मैंने एनोटेशन का उपयोग करके सब कुछ करने की कोशिश की लेकिन कोई किस्मत नहीं। – Brad

1

मैं XA लेनदेन और पुनरावर्तन का इस्तेमाल किया है खुला स्रोत टीएम Atomikos का उपयोग कर JUnit परीक्षण में। एक अच्छी विशेषता यह है कि एटमिकोस एक्सए लेनदेन में भाग लेने के लिए गैर-एक्सए सक्षम डेटा स्रोतों का उपयोग करने की अनुमति देता है। उदाहरण के लिए इस लिंक को देखें: http://www.atomikos.com/Documentation/NonXaDataSource

दूसरी तरफ, यदि एक्सए आपके जुनीट मुद्दों के लिए एक सभ्य समाधान है तो एक और कहानी है। क्या आपके परीक्षण डेटाबेस कार्यान्वयन (साइबेस) पर बहुत अधिक ध्यान केंद्रित करते हैं या जावा तर्क के बारे में अधिक जानकारी रखते हैं? मैं आमतौर पर सेटअप JUnit परीक्षण के लिए अपाचे डर्बी या HQSQL तरह डीबीएस एम्बेडेड। तब मैं साफ अप के बारे में ज्यादा देखभाल करने के लिए, के बाद से जी सी संभाल लेंगे कि :)

+0

आपकी प्रतिक्रिया के लिए धन्यवाद। डीबीयूनीट का उपयोग केवल टेस्ट डेटा लोड करने के लिए किया जा रहा है क्योंकि डेटासेट पहले ही किसी अन्य सेवा द्वारा उत्पादन में आबादी में आ जाएगा। इसलिए मेरे पास उत्पादन में कोई एक्सए समस्या नहीं है क्योंकि मैं केवल एक लक्ष्य डेटासोर्स को लिखता हूं। मुझे अपने "स्रोत" डेटा स्रोत के लिए एचएसक्यूएल का उपयोग करने का आपका विचार पसंद है। मुझे बस यह पता लगाना होगा कि एचएसक्यूएल के लिए अपनी स्कीमा को लोड करने के लिए कैसे सेट करें और इसे साइबेस स्कीमा के साथ संगत रखें। – Brad

+0

कोई भी जेटीए टीएम मेरे लिए अच्छा नहीं है क्योंकि मेरे डेटा स्रोत दोनों गैर-एक्सए हैं। अधिकांश जेटीए टीएम आपको ** एक ** गैर-एक्सए डेटासोर्स को शामिल करने की अनुमति देता है लेकिन – Brad

+0

एक बहुत लंबा शॉट नहीं है, लेकिन क्या है .. HQSQL छोड़ें, डेटा स्रोतों (स्रोत) में से एक के लिए अपाचे डर्बी का उपयोग करें। क्या आप स्कीमा को टेस्ट/संसाधन/source_db_setup.sql जैसे स्टोर नहीं कर सकते? डर्बी एक्सए सक्षम है। फिर आप अपने गैर-एक्सए स्रोत के रूप में sybase का उपयोग कर सकते हैं। मुझे लगता है कि आपके लिए कुछ और विकल्प होना चाहिए, हालांकि, इस समय मेरे पास कोई अच्छा विचार नहीं है। –