में ट्रांज़ेक्शन परिणामों के साथ उपयोग करके बहुत सारे डेटा डालने का मैं Grails 1.1 beta2 का उपयोग कर रहा हूं। मुझे अपने Grails आवेदन में बड़ी मात्रा में डेटा आयात करने की जरूरत है। यदि मैं बार-बार एक ग्रेल्स डोमेन क्लास को तुरंत चालू करता हूं और फिर इसे सहेजता हूं, तो प्रदर्शन अस्वीकार्य रूप से धीमा होता है। उदाहरण के लिए फोन बुक से लोगों को आयात करना:Grails, OutOfMemoryError
for (each person in legacy phone book) {
// Construct new Grails domain class from legacy phone book person
Person person = new Person(...)
person.save()
}
यह दर्दनाक रूप से धीमा हो जाता है। Grails मेलिंग सूची पर कोई सुझाव है कि बैचिंग एक लेनदेन में बचाता है। तो अब मेरे पास है:
List batch = new ArrayList()
for (each person in legacy phone book) {
// Construct new Grails domain class from legacy phone book person
Person person = new Person(...)
batch.add(person)
if (batch.size() > 500) {
Person.withTransaction {
for (Person p: batch)
p.save()
batch.clear()
}
}
}
// Save any remaining
for (Person p: batch)
p.save()
यह काम शुरू में कम से कम तेज़ होना चाहिए। प्रत्येक लेनदेन 500 रिकॉर्ड बचाता है। जैसे ही समय चल रहा है, लेन-देन लंबे और लंबे समय तक लगते हैं। पहले कुछ लेन-देन में लगभग 5 सेकंड लगते हैं, फिर यह वहां से निकलता है। लगभग 100 लेनदेन के बाद, प्रत्येक एक मिनट से अधिक समय लेता है, जो एक बार फिर अस्वीकार्य है। इससे भी बदतर यह है कि आखिरकार Grails जावा हीप मेमोरी से बाहर चला जाएगा। मैं जेवीएम ढेर आकार बढ़ा सकता हूं, लेकिन यह OutOfMemoryError
अपवाद में देरी करता है।
कोई विचार यह क्यों है? ऐसा लगता है कि कुछ आंतरिक संसाधन जारी नहीं किए जा रहे हैं। प्रदर्शन खराब हो जाता है, स्मृति जारी की जा रही है, और अंत में सिस्टम स्मृति से बाहर हो जाता है।
Grails documentation के अनुसार, withTransaction
स्प्रिंग के TransactionStatus
ऑब्जेक्ट को बंद कर देता है। लेनदेन को बंद/समाप्त करने के लिए मुझे TransactionStatus
में कुछ भी नहीं मिला।
संपादित करें: मैं Grails 'कंसोल से चल रहा हूँ (grails console
)
संपादित करें: यहाँ स्मृति अपवाद से बाहर बताया गया है:
Exception thrown: Java heap space
java.lang.OutOfMemoryError: Java heap space
at org.hibernate.util.IdentityMap.entryArray(IdentityMap.java:194)
at org.hibernate.util.IdentityMap.concurrentEntries(IdentityMap.java:59)
at org.hibernate.event.def.AbstractFlushingEventListener.prepareEntityFlushes(AbstractFlushingEventListener.java:113)
at org.hibernate.event.def.AbstractFlushingEventListener.flushEverythingToExecutions(AbstractFlushingEventListener.java:65)
at org.hibernate.event.def.DefaultFlushEventListener.onFlush(DefaultFlushEventListener.java:26)
at org.hibernate.impl.SessionImpl.flush(SessionImpl.java:1000)
at org.hibernate.impl.SessionImpl.managedFlush(SessionImpl.java:338)
at org.hibernate.transaction.JDBCTransaction.commit(JDBCTransaction.java:106)
at org.springframework.orm.hibernate3.HibernateTransactionManager.doCommit(HibernateTransactionManager.java:655)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.processCommit(AbstractPlatformTransactionManager.java:732)
at org.springframework.transaction.support.AbstractPlatformTransactionManager.commit(AbstractPlatformTransactionManager.java:701)
at org.springframework.transaction.support.TransactionTemplate.execute(TransactionTemplate.java:140)
क्या संदर्भ में यह निष्पादित किया जा रहा है? एक क्वार्ट्ज नौकरी? एक नियंत्रक? जब हमने एक नियंत्रक का उपयोग कर अतीत में ऐसा किया है, तो हमें एक लूप सेट करने की इजाजत दी गई है जो बैचिंग आकार को बाध्य कर सकती है, सेवा में बाद के लेनदेन के आकार के साथ संगत –