grails

2011-08-25 20 views
5

मैं एक grails ऐप्लिकेशन में पृष्ठभूमि प्रसंस्करण सेटअप की एक विशिष्ट प्रकार बनाने के लिए कोशिश कर रहा हूँ में पृष्ठभूमि धागे में हाइबरनेट कॉलिंग।grails

  • एक निश्चित आकार थ्रेड पूल केवल नौकरियों के बैच की अवधि
  • एक ही सत्र प्रत्येक थ्रेड द्वारा बनाए रखा है के लिए मौजूद है
  • प्रत्येक काम एक अलग लेन-देन में चलता है

मैं निम्नानुसार नौकरी शुरू करने की कोशिश कर रहा हूं:

int poolSize = 10 
ThreadFactory factory = new MyThreadFactory (Executors.defaultThreadFactory()) 
ExecutorService pool = Executors.newFixedThreadPool (poolSize, factory) 

(1..100).each { i -> 
    pool.submit { 
    try { 
     MyDomainClass.withTransaction { 
     doSomeWork(i) 
     } 
    } catch (Exception e) { 
     log.error "error in job ${i}", e 
    } 
    } 
} 

MyThreadFactory धागे जो एक हाइबरनेट सत्र धागा की अवधि के लिए संलग्न पैदा करता है।

class MyThreadFactory implements ThreadFactory { 

    ThreadFactory delegate 
    PersistenceContextInterceptor persistenceInterceptor 

    MyThreadFactory (ThreadFactory delegate) { 
    this.delegate = delegate 
    ApplicationContext applicationContext = ApplicationHolder.getApplication().getMainContext() 
    persistenceInterceptor = applicationContext.getBean("persistenceInterceptor"); 
    } 

    Thread newThread (Runnable work) { 
    return delegate.newThread { 
     persistenceInterceptor.init() 
     try { 
     work.run() 
     } finally { 
     persistenceInterceptor.flush() 
     persistenceInterceptor.destroy() 
     } 
    } 
    } 
} 

ऐसा लगता है, हालांकि पहली बार जब मैं बैच नौकरी चलाता हूं तो मुझे निम्न त्रुटि मिल जाएगी। कोई प्रभाव के साथ, (बाद में नौकरियों घटना के बिना चलाने)

groovy.lang.MissingMethodException: No signature of method: static MyDomainClass.save() is applicable for argument types: (java.util.LinkedHashMap) values: [[flush:false]] 
Possible solutions: save(), save(java.util.Map), save(java.lang.Boolean), wait(), any(), wait(long) 
at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) 
at ... 

मैं MyDomainClass.withNewSession {} साथ persitanceInterceptor की जगह की कोशिश की है।

ऐसा लगता है कि GORM तरीकों मेरे डोमेन कक्षाओं में इंजेक्शन नहीं जा रहा है।

किसी को भी मैं गलत क्या कर रही हूं, और क्यों बैच कार्य फिर से चलाने के देख सकते हैं यह सफल होने के लिए अनुमति देता है?

पूर्णता के लिए @fixitagain काम इस रूप ले लेता है:

doSomeWork = { id -> 
    MyDomainClass a = MyDomainClass.findById (id) 
    a.value = lotsOfWork() 
    a.save() 
} 

मेरा मानना ​​है कि लापता बचाने एक रेड हेरिंग है, जैसा कि मैंने एक सौदे में सक्रिय लपेटकर की कोशिश की, और फिर कह 'कोई त्रुटि मिलती है DomainClass.withTransaction (क्लोजर) 'परिभाषित नहीं किया गया है।

ऐसा लगता है कि पहली नौकरी दौड़ने में विफल रही है, लेकिन पहली नौकरी चलाने के बाद विफल हो जाती है, लेकिन कुछ के बाद सफलतापूर्वक चल रही है?) शुरू हो गया है।

+0

किस बिंदु पर वह Grails जीवन चक्र आप अपनी नौकरियां शुरू कर रहे हैं? ऐसा लगता है इससे पहले कि डोमेन और गतिशील तरीकों आदि –

+0

नौकरियों (अब के लिए) एक नियंत्रक कार्रवाई से ट्रिगर हो रहे हैं के साथ सजाया गया है जैसे कि यह होने वाली है, तो यह अच्छी तरह से करने के बाद डोमेन सजाया गया है है। मुझे ध्यान रखना चाहिए कि अगर मैं मुख्य धागे से सभी नौकरियों को बुलाता हूं, तो कोई समस्या नहीं होती है। – Akusete

+0

अच्छी तरह से, मेरे लिए GORM "संलग्न" है क्योंकि यह संभावित समाधान के रूप में सहेजने (मानचित्र) का प्रस्ताव दे रहा है। क्या आप उस लाइन को डाल सकते हैं जहां आप सहेज रहे हैं। BTW फ्लश डिफ़ॉल्ट रूप से गलत है, जिसका अर्थ यह हाइबरनेट सत्र के अंत में फ्लश ... – fixitagain

उत्तर

1

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

Grails Executor Plugin यदि आपके पास इसका उपयोग करने में आरक्षण है, तो आप अपनी खुद की थ्रेडिंग रणनीति लिखने से पहले इसके कोड को देख सकते हैं।

+0

मैं निष्पादक प्लगइन पर एक नज़र लिया है, यह भी नए धागे में एक सत्र बनाने के लिए persistenceInterceptor उपयोग करता है। फिलहाल मैं यह सुनिश्चित करने में अधिक रुचि रखता हूं कि मैं पूरी तरह से समझता हूं कि प्लगइन का उपयोग करने से पहले grails/hibernate कैसे काम करता है। लेकिन इसका जिक्र करने के लिए धन्यवाद। – Akusete

+0

निष्पादक प्लगइन पर एक दूसरे रूप के बाद, यह हमेशा प्रति नौकरी एक नया सत्र बना देगा। जो सामान्य रूप से समझ में आता है, लेकिन मेरे द्वारा किए जाने वाले विशिष्ट कार्य के लिए नहीं। हालांकि प्लगइन के रूप में सत्र बनाने के लिए मैं सटीक उसी तंत्र का उपयोग करने की कोशिश कर रहा हूं। – Akusete

+0

आप क्वार्ट्ज प्लगइन का उपयोग क्यों नहीं करते? http://grails.org/plugin/quartz – felipenasc

0

मैं कोड या नामकरण सम्मेलन से बाहर नहीं निकल सकता, लेकिन क्या आप वाकई डोमेन क्लास के उदाहरण पर सहेज रहे हैं?

+0

मुझे लगता है कि त्रुटि संदेश के साथ 'quirk' था, मैं एक डोमेन क्लास उदाहरण पर defiantly सेव() को बुला रहा हूँ। साथ ही, मुझे लगता है कि अगर यह समस्या थी तो यह समझा नहीं जाएगा कि जब मैं इसे दूसरी बार चलाता हूं तो नौकरी सफलतापूर्वक खत्म क्यों होगी। A.save() को कॉल करने से पहले – Akusete

+0

, a = a.merge() मदद करता है? – bluesman

0

गायब विधि अपवाद का तात्पर्य है कि आप वर्ग पर सहेज रहे हैं, उदाहरण के लिए नहीं।

संपादित करें: GORM पहले से ही अतिरिक्त विधियों को लागू कर चुका है, जैसा कि आप सुझाए गए समाधान विधि नामों में देख सकते हैं।