7

मेरा प्रोजेक्ट वसंत लेनदेन प्रबंधक के साथ हाइबरनेट का उपयोग कर रहा है और मेरा डेटाबेस पोस्टग्रेज़ (अप्रासंगिक हो सकता है)।डेटाबेस बाधा को हाइबरनेट

मैं बड़ी एक्सएमएल फाइलें पढ़ने और उन वस्तुओं में से वस्तुओं का निर्माण करने की कोशिश कर रहा हूं (वस्तुएं बड़ी नहीं हैं लेकिन राशि है) और उन्हें डेटाबेस में डालें।

यदि किसी मौके से मेरी ऑब्जेक्ट्स में से एक डेटाबेस बाधा का उल्लंघन करती है तो पूरी प्रक्रिया बंद हो जाती है। मैं डेटाबेस बाधा का उल्लंघन करने वाले लोगों को कैसे छोड़ सकता हूं? वैकल्पिक रूप से अपनी आईडी या लॉग फ़ाइल के लिए जो कुछ भी लॉग इन करें?

प्रश्न अद्यतन:

मैं इतना गर्त ब्राउज़ कर दिया गया है और पाया है कि बैच आवेषण के लिए यह सबसे अच्छा स्टेटलेस सत्र का उपयोग करने की सिफारिश की है, लेकिन मैं अभी भी एक ही मुद्दे और डालने मिल बंद हो जाता है:

May 26, 2012 4:45:47 PM org.hibernate.util.JDBCExceptionReporter logExceptions 
SEVERE: ERROR: duplicate key value violates unique constraint "UN_FK" 
    Detail: Key (fid)=(H1) already exists. 

यहाँ XML पार्सिंग और डाटाबेस में डालने के लिए अपने कोड के प्रासंगिक भागों रहे हैं, सादगी के लिए चलो मान मैं डालने फिल्में कर रहा हूँ:

//class field 
@Autowired 
private SessionFactory sessionFactory; 

@Override 
public void startDocument() throws SAXException { 
    session = sessionFactory.getCurrentSession(); 
} 

@Override 
public void endElement(String uri, String localName, String qName) throws SAXException { 
if (qName.equalsIgnoreCase("FILM")) { 
     movie.setCategory(category); 
     movie.setAdded(new Date()); 
     session.insert(movie); 
    } 
} 

मैं और यह संपत्ति ऐप-सीटीएक्स hibernate.jdbc.batch_size से 100 में सेट की है। क्या इससे बचने के लिए डालने से पहले चयन करना वास्तव में आवश्यक है?

अद्यतन 2:

अगर मैं सत्र के बजाय StatelessSession उपयोग करते हैं, मैं arround 20 आवेषण हो और प्रसंस्करण बंद हो जाता है अनिश्चित काल के लिए किसी भी अपवाद या कुछ भी बिना से।

मुझे लगता है कि नंबर 20 है क्योंकि मैं टोमकैट के साथ कनेक्शन पूल कर रहा हूं और maxActive="20" है।

बाउंटी अद्यतन:

मैं वास्तव में कोई प्रस्ताव समाधान (यदि संभव हो तो बचाव की मुद्रा में चयन के बिना) को देखने के लिए अच्छा लगेगा। StatelessSession या बस सत्र का उपयोग करना। इस तरह यदि एक स्तंभ नल है या एक अधिकतम चौड़ाई है के रूप में बाधाओं के

उत्तर

4

अधिकांश प्रकार,, आप Hibernate Validator का उपयोग कर सकते हैं। इसे जारी रखने का प्रयास करने से पहले ऑब्जेक्ट पर सत्यापन को मैन्युअल रूप से निष्पादित करें।

कुछ चीजों के लिए, विशेष रूप से अद्वितीय बाधाओं के लिए, आपको या तो टकराव मौजूद है या नहीं, यह देखने के लिए कि आप पहले से डाले गए मानों के स्मृति सेट में एक 'रक्षात्मक' चयन निष्पादित करने की आवश्यकता है।

2

किसी XML फ़ाइल से बड़ी मात्रा में ऑब्जेक्ट्स डालने के लिए, आपको वसंत बैच का उपयोग करने पर विचार करना चाहिए। पैरामीटर स्किप-सीमा आपको यह बताने की अनुमति देती है कि बैच प्रक्रिया को रोकने से पहले आपके एक्सएमएल में कितनी ग़लत लाइनें हो सकती हैं। स्किप-पॉलिसी और छोड़ने योग्य-अपवाद भी जांचें; वसंत दस्तावेज में Configuring a Step देखें।

यदि आप वसंत बैच का उपयोग नहीं करना चाहते हैं, तो बस एक सरल प्रयास पकड़ का उपयोग करें जो आपकी प्रक्रिया को अंत तक जारी रखने की अनुमति देगा।

+0

एक साधारण कोशिश पकड़ बयान से काम नहीं चलेगा:

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

+0

इसीलिए इस तरह के मामलों के लिए एक स्टेटलेस हाइबरनेट सत्र का उपयोग करने की सिफारिश की जाती है। यह असंगत स्थिति को रोक देगा और स्मृति खपत को भी कम करेगा (या आपको पहले से ही इलाज की गई संस्थाओं को बेदखल नहीं करना पड़ेगा) –

1

मुझे लगता है कि Affe में डालने से पहले रक्षात्मक चयन के साथ सही दृष्टिकोण है।

आप प्रत्येक डालने से पहले savepoint का उपयोग करने पर विचार कर सकते हैं और अपवाद फेंकने पर सहेजने के लिए वापस रोलिंग पर विचार कर सकते हैं। एक बचत बिंदु बनाने का एक प्रदर्शन ओवरहेड होगा। जब आप पूरा कर लेंगे तो सेवपॉइंट को रिलीज़ होने की आवश्यकता होगी।

AbstractTransactionStatus.setSavepoint() देखें या आप JDBC कनेक्शन पूल के लिए उपयोग किया है, तो setSavepointrollback(Savepoint) और releaseSavepoint(Savepoint)

2

तुम क्यों यह सब एक बड़ा लेन-देन हो गया है लगता है? वास्तव में जो कुछ भी आप वर्णन करते हैं, वह मेरा तात्पर्य है कि वास्तव में आपके यहां कई लेन-देन हैं। उन वस्तुओं के लिए जो "त्रुटि आउट" करते हैं, केवल उस इकाई को बेदखल करें और लेनदेन को रोलबैक करें। यदि "फिल्म" तत्व ऑब्जेक्ट्स के ग्राफ को परिभाषित करता है, तो यह थोड़ा और जटिल हो जाता है, लेकिन विचार समान है।

4

मुझे लगता है कि ऐसा कुछ पूर्ण रूप से मान्य करना असंभव है कि आप सफल सम्मिलन की गारंटी दे सकते हैं। कुछ मामलों में, आप जो भी करते हैं, कोई फर्क नहीं पड़ता, कोई और बाध्यता के बीच डीबी में कुछ डाल सकता है और बाधा उल्लंघन का कारण बन सकता है।

ज्यादातर मामलों में मैं बस किसी अन्य की तरह अपवाद को संभालने की अनुशंसा करता हूं।

0

हालांकि यह एक पुराना सवाल है, मुझे हाल ही में इसी तरह की स्थिति का सामना करना पड़ा और मैंने जो किया वह मैंने किया।

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

try { 
    session.connection().setSavePoint("lastSaved"); 
    session.insert(obj); 
} 
catch(ConstraintViolationException) { 
    log.error(obj.getUserId()); 
    .... 
} 
tx.commit(); 
.... 
catch(TransactionException e) { 
    tx.rollback(); 
} 
संबंधित मुद्दे