2011-12-02 14 views
8

के बारे में कुछ प्रश्न मैं Grails वेब एप्लिकेशन के साथ काम कर रहा हूं और मुझे Grails सेवा का उपयोग करते समय बहुत सारी अजीब चीजें मिलती हैं। तो मैं Grails सेवाओं के बारे में और अधिक समझने के लिए इस पर कुछ सवाल पूछना चाहता हूँ। यह मेरे लिए बहुत उपयोगी होगा (और शायद दूसरों के लिए^_ ^)। अग्रिम में धन्यवाद।Grails सेवा

  1. एक सेवा स्थिर व्यवहार के साथ कॉन्फ़िगर किया गया है = सच है, यह किसी भी विधि के बाद डीबी के लिए हर डाटा परिवर्तन एक वस्तु जो गंदे और हाइबरनेट सत्र में बंद किया जा रहा है साथ आह्वान फ्लश होगा?

  2. क्या मैं static transactional = true के बजाय कक्षा स्तर पर @Transactional एनोटेशन का उपयोग कर सकता हूं? और क्या यह कुछ तरीकों से @Transactional(readOnly = true) डालने के लिए संभव है कि मैं सिर्फ उन्हें डीबी से डेटा (क्वेरी, ढूंढें) डेटा पढ़ना चाहता हूं?

  3. लेनदेन विरासत के बारे में कैसे? मेरा मतलब है कि, यदि अभिभावक सेवा static transactional = true कॉन्फ़िगर की गई है, और बच्चे सेवा के पास @Transactional एनोटेशन (कक्षा पर) और कुछ @Transactional(readOnly = true) (कुछ तरीकों से) है, तो क्या होगा यदि मैं बच्चे से माता-पिता पर एक विधि कहूं?

  4. क्या एक अमूर्त सेवा के साथ लेनदेन का काम करता है? क्योंकि जैसा कि मुझे पता है, अमूर्त सेवा के साथ हम अपनी बीन शुरू नहीं कर सकते हैं, और शायद ऐप शुरू करते समय, Grails संदर्भ में कुछ अंतर हैं।/स्प्रिंग हाइबरनेट एकीकरण सुनिश्चित करता है कि एक फ्लश होता है से पहले प्रतिबद्ध -

उत्तर

7

आप सवाल प्रति एक सवाल :)

# 1 प्रश्न के लिए, हाँ पूछना चाहिए। तो save() और delete() पर कॉल किया जाएगा और flush: true को जोड़ने की आवश्यकता नहीं है। इसके अलावा, गंदे उदाहरण जिन्हें आपने save() पर कॉल नहीं किया है, तब तक फ़्लश नहीं किया जाएगा जब तक कि आप discard() पर कॉल न करें।

# 2 के लिए: सेवाएं डिफ़ॉल्ट रूप से लेनदेन होती हैं, इसलिए transactional = true वास्तव में अनावश्यक है - आपको केवल transactional = false कहने के लिए इसे निर्दिष्ट करने की आवश्यकता है। लेकिन बनाया गया स्वचालित लेनदेन रैपर केवल तभी किया जाता है जब @Transactional एनोटेशन न हों। यदि आपके पास एक या अधिक एनोटेशन हैं तो वे लेनदेन की सीमा को परिभाषित करते हैं। तो डिफ़ॉल्ट रूप से (यानी कोई टिप्पणी नहीं है और या तो transactional संपत्ति या transactional = true) सभी विधियां लेन-देन हैं, लेकिन यदि आप केवल विधियों का सबसेट एनोटेट करते हैं तो केवल वे लेनदेन होंगे।

आमतौर पर जब आप गैर-डिफ़ॉल्ट व्यवहार चाहते हैं तो एनोटेशन का उपयोग करेंगे, यानी कस्टम प्रचार, अलगाव, टाइमआउट, आदि (या इसे केवल आपके उदाहरण में पढ़ने के लिए)।

आप कक्षा के स्तर पर सभी विधियों के लिए समान कॉन्फ़िगरेशन के लिए एनोटेट कर सकते हैं, और क्लास-स्कोप डिफ़ॉल्ट को ओवरराइड करने के लिए व्यक्तिगत तरीकों को वैकल्पिक रूप से एनोटेट कर सकते हैं।

# 3 और # 4 के लिए, मानक नियम लागू होते हैं (देखें # 2)। यदि उप-वर्ग में एनोटेशन हैं, तो उस कक्षा या माता-पिता वर्ग से transactional = true को एनोटेशन का उपयोग करके अनदेखा कर दिया जाएगा, जिसे आपने Grails को बताया है कि आप स्वयं चीजों को कॉन्फ़िगर कर रहे हैं।

चूंकि अमूर्त सेवाओं को तत्काल नहीं किया जा सकता है, इसलिए ठोस उपclass जो वास्तव में तत्काल है, मूल वर्ग और स्वयं से संयुक्त व्यवहार होगा। यदि सब कुछ transactional = true है तो यह आसान है, और यदि आपके पास कोई टिप्पणी है तो वे नियमों को परिभाषित करते हैं।

सुपरक्लास में कॉलिंग विधियां मौजूदा कक्षा में कॉलिंग विधियों की तरह व्यवहार करेंगी। लेकिन व्यवहार थोड़ा सा अंतर्ज्ञानी है यदि आपने स्प्रिंग के प्रॉक्सी दृष्टिकोण के प्रभावों पर विचार नहीं किया है। जब आप एक लेनदेन विधि कहते हैं, प्रॉक्सी कॉल को रोकती है और सक्रिय लेनदेन में शामिल हो जाती है, या यदि आवश्यक हो तो एक नया शुरू होता है, या यदि REQUIRES_NEW निर्दिष्ट किया गया है तो एक नया शुरू होता है। लेकिन एक बार जब आप असली कक्षा में हों और दूसरी विधि को कॉल करें, तो आप प्रॉक्सी को बाईपास कर देंगे। तो यदि आप अलग-अलग एनोटेशन सेटिंग्स के साथ एक और तरीका कहते हैं, तो उन्हें अनदेखा कर दिया जाएगा। यदि आप ऐसा करने जा रहे हैं, तो क्या हो रहा है इसके बारे में यह मेलिंग सूची चर्चा देखें और इसके साथ कैसे काम करें: http://grails.1312388.n4.nabble.com/non-transactional-service-extends-transactional-service-outcome-td3619420.html

+0

बहुत बढ़िया! आपके स्पष्ट उत्तरों के लिए बहुत बहुत धन्यवाद। लेकिन रिवर्स साइड के साथ बिंदु # 3 पर एक नज़र डालें: अभिभावक सेवा ए को क्लास लेवल पर @ एन्नोटेशन चिह्नित किया गया है और ए में विधि doParent() पढ़ा जाता है केवल पढ़ने के लिए, जबकि बच्चे सेवा बी में लेनदेन के बारे में कोई विशिष्ट कॉन्फ़िगरेशन नहीं है। मैं बी से DoParent() को क्यों कॉल करता हूं, फिर भी यह डेटा फ्लश करता है हालांकि मैं इसे पढ़ने के लिए मजबूर करता हूं केवल? –