2011-03-09 4 views
5

से फेंक दिया गया है, मैंने हाल ही में स्प्रिंग के डेटा स्रोत लेनदेन प्रबंधक का उपयोग करना शुरू कर दिया है। मुझे अब एक समस्या है। मेरे लेनदेन में एक डीबी तालिका के अपडेट और फ़ाइल में एक लेखन ऑपरेशन शामिल है।लेन-देन का प्रबंधन कैसे करें (जिसमें फ़ाइल IO शामिल है) जब IOException को बंद फ़ाइल विधि

यह ठीक काम करता है लेकिन मुझे फ़ाइल I/O के बारे में कुछ संदेह हैं। जैसा कि आप नीचे देखते हैं, मैंने अपने बीन के ओपनफाइल और क्लोज़फाइल विधियों को क्रमशः इनिट-विधि और विनाश-विधि के रूप में कॉन्फ़िगर किया है, जो बदले में उन तरीकों को एक कंसुक्टर और विनाशक के रूप में बुलाया जाता है। अगर फ़ाइल ठीक से बंद नहीं है, तो कुछ रिकॉर्ड आउटपुट.txt फ़ाइल में सफलतापूर्वक लिखे नहीं गए हैं जिसका अर्थ है कि मैं लेनदेन प्रबंधन को भी ठीक से संभालने में सक्षम नहीं हूं।

हालांकि, मैं उन डीबी अपडेट को रोलबैक करना चाहता हूं जिन्हें फ्लैट फ़ाइल में शामिल नहीं किया गया है। मेरे समाधान के साथ, लेनदेन में फ़ाइल क्लोज़ विधि को जोड़ना असंभव लगता है। क्या कोई इस वांछित कार्रवाई को सही ढंग से कार्यान्वित करने के बारे में जानता है?

कोई सुझाव बहुत सराहना की जाएगी

<!--XML CONFIGURATION --> 
<bean id="myFileWriter" class="com.job.step.ItemFileWriter" init-method="openFile" destroy-method="closeFile"> 
    <property name="jdbcTemplate" ref="jdbcTemplateProduct"/> 
</bean> 

public class ItemFileWriter implements ItemWriter<Item> { 
private static final Logger log = Logger.getLogger(ItemFileWriter.class); 
private BufferedWriter bw = null; 
public void openFile() throws IOException { 
    try { 
     bw = new BufferedWriter(new FileWriter("C:\\output.txt")); 
    } catch (IOException e) {   
     //log.error(e); 
     throw e; 
    }  
} 
public void closeFile() throws IOException { 
    if (bw != null) { 
     try { 
      bw.close(); 
     } catch (IOException e) { 
      log.error(e); 
      throw e; 
     } 
    } 
} 

@Transactional(rollbackFor = IOException.class) 
public void write(List<? extends Item> itemList) throws IOException 
{    
    for (Iterator<? extends Item> iterator = itemList.iterator(); iterator.hasNext();) { 
     Item item = (Item) iterator.next(); 

     String updateRtlnOutbound = "UPDATE SAMPLESCHEMA.SAMPLETABLE SET STATUS='TRANSFERRED' WHERE ID = ?"; 
     jdbcTemplate.update(updateRtlnOutbound, new Object[]{item.getID()}); 

     String item = String.format("%09d\n", item.customerNumber); 
     bw.write(item); 
    }       
} 
} 

उत्तर

3

सामान्य शब्दों में, फ़ाइल आईओ नहीं व्यवहार (कुछ ओएस विशिष्ट सुविधाओं को छोड़कर) है।

तो, सबसे अच्छा आप कर सकते हैं कि आप लेनदेन के अंदर निष्पादित करने के लिए खुले और बंद ऑपरेशन को write() विधि पर ले जाएं और बंद होने पर लेनदेन को रोलबैक करें।

नोट, हालांकि, आप लेनदेन रोलबैक के मामले में फ़ाइल IO को रोलबैक नहीं कर सकते हैं, ताकि कुछ परिस्थितियों में आप आइटम के साथ सही फ़ाइल प्राप्त कर सकें, जबकि डेटाबेस में इन आइटमों को TRANSFERRED के रूप में चिह्नित नहीं किया गया है।

इस समस्या low-level transaction management support का उपयोग करें और रोलबैक के मामले में फ़ाइल को हटाने का प्रयास करने के लिए कोशिश कर सकते हैं sove करने के लिए, लेकिन मुझे लगता है कि यह अभी भी स्थिरता की मजबूत गारंटी प्रदान नहीं कर सकते हैं:

@Transactional(rollbackFor = IOException.class) 
public void write(List<? extends Item> itemList) throws IOException 
{     
    openFile(); 
    TransactionSynchronizationManager().registerSynchronization(new TransactionSynchronizationAdapter() { 
     public void afterCompletion(int status) { 
      if (status = STATUS_ROLLED_BACK) { 
       // try to delete the file 
      } 
     } 
    }); 

    try { 
     ... 
    } finally { 
     closeFile();       
    } 
} 
2

आप क्या कर रहे हैं दो अलग-अलग प्रणालियों पर संचालन: फ़ाइल-सिस्टम और डेटाबेस। आम तौर पर, एक्सए लेनदेन हमारे लिए एक ही लेनदेन में विभिन्न लेनदेन प्रणालियों को गठबंधन करना आसान बनाता है।

अधिकांश डेटाबेस XA लेनदेन में भाग लेने के लिए किए जा सकते हैं। फ़ाइल-सिस्टम के लिए आप XA को सक्षम करने के लिए XADisk का उपयोग कर सकते हैं। एक बार जब आप दोनों डेटाबेस (डेटा-स्रोत की सही कॉन्फ़िगरेशन के माध्यम से) और फ़ाइल-सिस्टम (xadisk के माध्यम से) पर एक्सए सक्षम करते हैं, तो आप सुनिश्चित कर सकते हैं कि फ़ाइल और डेटाबेस संचालन दोनों या दोनों रोलबैक हैं।

संबंधित मुद्दे