2012-05-14 11 views
23

का उपयोग करके बैच आवेषण क्या कोई तरीका है जहां हम जेपीए EntityManager का उपयोग कर बैच आवेषण का उपयोग कर सकते हैं। मुझे पता है कि इसे हासिल करने का कोई सीधा तरीका नहीं है लेकिन इस तंत्र को हासिल करने के लिए कुछ रास्ता होना चाहिए।जेपीए EntityManager

वास्तव में, प्रत्येक सम्मिलन ऑपरेशन के लिए यह मुझे 300ms ले रहा है जिसे मैं एकल आवेषण के बजाय बैच आवेषण का उपयोग करना चाहता हूं।

यहाँ कोड मैं वर्तमान में एक आवेषण

 @PersistenceContext(unitName = "testing") 
     EntityManager eM; 

     Query querys = this.eM.createNativeQuery(insertQuery); 
     for (String s : someList) { 
      //setting parameters 
      querys.executeUpdate(); 
     } 

अग्रिम धन्यवाद के लिए क्रियान्वित करने का उपयोग कर रहा है।

उत्तर

11

यह जेपीए का उपयोग करके बैच लिखने के लिए संभव है, लेकिन यह आपके दृढ़ता प्रदाता, डेटाबेस और जेडीबीसी चालक के विशिष्ट कार्यान्वयन पर अत्यधिक निर्भर है। उदाहरण के लिए, यह article बताता है कि EclipseLink JPA 2.3 और ओरेकल डेटाबेस का उपयोग करके बैच लेखन (ऑप्टिमाइज़ेशन # 8) को कैसे सक्षम करें। अपने विशेष वातावरण में समान कॉन्फ़िगरेशन पैरामीटर के लिए देखें।

+0

हाय, यू मुझे कुछ कोड प्रदान कर सकते हैं झलकी कैसे ऊपर दिया गया कोड एक ही उपयोग करने के लिए। – Ran

+0

@Rana जैसा कि मैंने ऊपर बताया है: यह इस बात पर निर्भर करता है कि आप किस निरंतरता प्रदाता का उपयोग कर रहे हैं - और मैं कोड को देखकर नहीं बता सकता, आपको मुझे बताना होगा। –

+1

हाय, मैं org.eclipse.persistence.jpa.PersistenceProvider का उपयोग कर रहा हूँ। अगर बैच आवेषण का उपयोग कर कोई सीमाएं हैं तो कृपया मुझे बताएं। – Ran

3

जेपीए के पास बैचिंग के लिए कोई सेटिंग नहीं है। हालांकि कुछ कार्यान्वयन-निर्भर सेटिंग्स हैं। Here is an example for hibernate

21

लेनदेन को लूप संलग्न करने के आधार पर, बैचिंग आम तौर पर आपके मामले में पहले से ही होती है।

जेपीए आपके सभी अपडेट अपने एल 1 कैश में एकत्र करेगा, और आमतौर पर लेनदेन करते समय बैच में डीबी को सभी लिखते हैं। यह वास्तव में जेडीबीसी में बैचिंग के साथ अलग नहीं है, जहां आप जो भी बैच-आइटम जोड़ते हैं वह अस्थायी रूप से स्मृति में तब तक होता है जब तक आप अपडेट विधि को कॉल नहीं करते।

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

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

अंत में, आपको पता होना चाहिए कि आपका एल 1 कैश लूप में बढ़ता रहता है, इसलिए यदि अपडेट की संख्या वास्तव में बड़ी है, तो समय-समय पर इसे साफ़ करें। वैकल्पिक रूप से, यदि आपका व्यावसायिक तर्क इसे बनाए रख सकता है, तो एकाधिक लेनदेन में आंशिक अपडेट करें। जैसे लेनदेन में आइटम 0 से 100,000 1, 100.001 से 200.000 लेनदेन 2, आदि

+0

अरे मैंने अब वसंत डेटा जेपीए का उपयोग किया है, तो आपका मतलब है कि अगर मैं किसी विधि के अंदर एक लूप में ऑब्जेक्ट अपडेट करता हूं और यह विधि @ ट्रान्सएक्शनल द्वारा चिह्नित की जाती है, तो यह स्वचालित रूप से जेडीबीसी बैच अपडेट की तरह अपडेट बैच करेगा। – zhuguowei

12

मुझे पता है कि यह एक स्वीकार्य उत्तर के साथ एक काफी पुराना सवाल है। फिर भी, मैं इस विशिष्ट विषय "जेपीए बैच आवेषण" का एक नया जवाब देना चाहता हूं।

@PersistenceContext 
private EntityManager entityManager; 

@Value("${hibernate.jdbc.batch_size}") 
private int batchSize; 

public <T extends MyClass> Collection<T> bulkSave(Collection<T> entities) { 
    final List<T> savedEntities = new ArrayList<T>(entities.size()); 
    int i = 0; 
    for (T t : entities) { 
    savedEntities.add(persistOrMerge(t)); 
    i++; 
    if (i % batchSize == 0) { 
     // Flush a batch of inserts and release memory. 
     entityManager.flush(); 
     entityManager.clear(); 
    } 
    } 
    return savedEntities; 
} 

private <T extends MyClass> T persistOrMerge(T t) { 
    if (t.getId() == null) { 
    entityManager.persist(t); 
    return t; 
    } else { 
    return entityManager.merge(t); 
    } 
} 

स्रोत: http://frightanic.com/software-development/jpa-batch-inserts/

+2

मुझे लगता है कि हमें अपने बैच आकार को पूरा नहीं करने वाले किसी भी शेष ऑब्जेक्ट को सहेजने के लिए अंत में फिर से फ्लश() 'और' clear() 'की आवश्यकता है? –

+0

सही लगता है, धन्यवाद @ रामपात्रा। –

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