java - @ ट्रांसेक्शन एनोटेशन कहां है?




spring annotations (12)

आदर्श रूप में, सेवा परत (प्रबंधक) आपके व्यापार तर्क का प्रतिनिधित्व करता है और इसलिए इसे @Transactional ट्रांसेक्शनल के साथ एनोटेट किया जाना चाहिए। सेवा परत डीबी संचालन करने के लिए विभिन्न डीएओ को कॉल कर सकती है। आइए ऐसी परिस्थितियों को मानें जहां आपके पास सेवा विधि में डीएओ संचालन की संख्या है। यदि आपका पहला डीएओ ऑपरेशन असफल रहा, तो अन्य अभी भी पास हो सकते हैं और आप असंगत डीबी राज्य समाप्त कर देंगे। एनोटेटिंग सर्विस लेयर आपको ऐसी स्थितियों से बचा सकता है।

क्या आपको DAO कक्षाओं और / या उनके तरीकों में @Transactional रखना चाहिए या डीएओ ऑब्जेक्ट्स का उपयोग कर कॉलिंग सेवा कक्षाओं को एनोटेट करना बेहतर है? या क्या यह "परतों" दोनों को एनोटेट करने के लिए समझ में आता है?


आम तौर पर मैं दूसरों से सहमत हूं कि लेन-देन आमतौर पर सेवा स्तर पर शुरू होते हैं (ग्रैन्युलरिटी के आधार पर जो आपको निश्चित रूप से आवश्यक है)।

हालांकि, इस बीच में मैंने अपनी डीएओ परत (और अन्य परतों को लेनदेन शुरू करने की अनुमति नहीं है, लेकिन मौजूदा लोगों की आवश्यकता है) में @Transactional(propagation = Propagation.MANDATORY) जोड़ने शुरू कर दिया है क्योंकि आपके पास त्रुटियों का पता लगाना बहुत आसान है कॉलर में एक लेनदेन शुरू करने के लिए भूल गए (उदाहरण के लिए सेवा)। यदि आपके डीएओ को अनिवार्य प्रचार के साथ एनोटेट किया गया है तो आपको यह अपवाद मिलेगा कि विधि लागू होने पर कोई सक्रिय लेनदेन नहीं है।

मेरे पास एक एकीकरण परीक्षण भी है जहां मैं इस एनोटेशन के लिए सभी बीन्स (बीन पोस्ट प्रोसेसर) की जांच करता हूं और विफल रहता हूं यदि एक बीन में अनिवार्यता के अलावा प्रचार के साथ @ @Transactional एनोटेशन है जो सेवा परत से संबंधित नहीं है। इस तरह से मैं सुनिश्चित करता हूं कि हम गलत परत पर लेनदेन शुरू नहीं करते हैं।



डेटाबेस स्तर में लेनदेन के लिए

ज्यादातर मैंने डीएओ में बस विधि स्तर पर @Transactional का उपयोग किया, इसलिए कॉन्फ़िगरेशन विशेष रूप से एक विधि / डिफ़ॉल्ट (आवश्यक) के लिए हो सकता है

  1. डीएओ की विधि जो डेटा लाने (चयन ..) प्राप्त करती है - आपको @Transactional आवश्यकता नहीं है, इससे लेनदेन इंटरसेप्टर / और एओपी प्रॉक्सी की वजह से कुछ ओवरहेड हो सकता है जिसे निष्पादित करने की आवश्यकता होती है।

  2. डीएओ के तरीके जो सम्मिलित / अद्यतन करते हैं उन्हें @Transactional मिलेगा

transctional पर बहुत अच्छा ब्लॉग

आवेदन स्तर के लिए -
मैं व्यापार तर्क के लिए लेनदेन का उपयोग कर रहा हूं मैं अप्रत्याशित त्रुटि के मामले में रोलबैक सक्षम करना चाहता हूं

@Transactional(rollbackFor={MyApplicationException.class})
public void myMethod(){

    try {    
        //service logic here     
    } catch(Throwable e) {

        log.error(e)
        throw new MyApplicationException(..);
    }
}

पारस्परिक टिप्पणियां उन सभी परिचालनों के आस-पास रखी जानी चाहिए जो अविभाज्य हैं।

उदाहरण के लिए, आपका कॉल "पासवर्ड बदलें" है। इसमें दो ऑपरेशन होते हैं

  1. पासवर्ड बदलें।
  2. परिवर्तन की लेखा परीक्षा।
  3. क्लाइंट को ईमेल करें कि पासवर्ड बदल गया है।

तो उपर्युक्त में, यदि ऑडिट विफल रहता है, तो क्या पासवर्ड परिवर्तन भी असफल हो सकता है? यदि ऐसा है, तो लेनदेन लगभग 1 और 2 होना चाहिए (इसलिए सेवा परत पर)। अगर ईमेल विफल रहता है (शायद इस पर किसी प्रकार का असफल सुरक्षित होना चाहिए तो यह असफल नहीं होगा) तो क्या इसे परिवर्तन पासवर्ड और ऑडिट वापस लेना चाहिए?

@Transactional कहां रखना है यह तय करते समय आपको पूछे जाने वाले प्रश्नों के बारे में पूछे जाने वाले प्रश्न हैं।


मुझे लगता है कि लेनदेन सेवा परत पर हैं। यह वह है जो काम की इकाइयों और मामलों का उपयोग करने के बारे में जानता है। यह सही जवाब है यदि आपके पास ऐसी सेवा में इंजेक्शन देने वाले कई डीएओ हैं जिन्हें एक ही लेनदेन में एक साथ काम करने की आवश्यकता है।


मैं विधि स्तर पर सेवा परत पर @Transactional का उपयोग करना पसंद करते हैं।


सबसे पहले हम परिभाषित करते हैं कि हमें लेनदेन का उपयोग करना है ?

मुझे लगता है कि सही उत्तर है - जब हमें यह सुनिश्चित करने की ज़रूरत है कि कार्यों का अनुक्रम एक परमाणु संचालन के रूप में एक साथ समाप्त हो जाएगा या कोई भी क्रिया तब भी नहीं की जाएगी जब कोई भी कार्य विफल हो जाए।

सेवाओं में व्यापार तर्क डालने के लिए यह अच्छी तरह से ज्ञात अभ्यास है। इसलिए सेवा विधियों में विभिन्न क्रियाएं हो सकती हैं जिन्हें काम की एक तार्किक इकाई के रूप में किया जाना चाहिए। यदि ऐसा है - तो ऐसी विधि को लेनदेन के रूप में चिह्नित किया जाना चाहिए। बेशक, हर विधि को ऐसी सीमा की आवश्यकता नहीं होती है, इसलिए आपको पूरी सेवा को लेनदेन के रूप में चिह्नित करने की आवश्यकता नहीं है।

और भी अधिक - यह ध्यान में रखना न भूलें कि @ ट्रांस्सेक्शन स्पष्ट रूप से, विधि प्रदर्शन को कम कर सकता है। पूरी तस्वीर देखने के लिए आपको लेनदेन अलगाव स्तरों को जानना होगा। यह जानकर कि आपको @ ट्रांसेक्शनल का उपयोग करने से बचने में मदद मिल सकती है जहां इसकी जरुरत नहीं है।


सामान्य मामला सेवा स्तर स्तर पर एनोटेट करना होगा, लेकिन यह वास्तव में आपकी आवश्यकताओं पर निर्भर करता है।

सेवा परत पर टिप्पणी करने से डीएओ स्तर पर एनोटेट करने से अधिक लेन-देन होंगे। लेनदेन अलगाव स्तर के आधार पर जो समस्याएं पैदा कर सकते हैं, क्योंकि समवर्ती लेन-देन उदाहरण में एक-दूसरे के परिवर्तन नहीं देख पाएंगे। दोहराने योग्य पढ़ें।

डीएओ पर टिप्पणी करना लेनदेन को जितना संभव हो उतना छोटा रखेगा, इस बात की कमी के साथ कि आपकी सेवा परत की कार्यक्षमता एक एकल (रोलबैक करने योग्य) लेनदेन में नहीं की जाएगी।

प्रचार मोड को डिफ़ॉल्ट पर सेट किया गया है, तो दोनों परतों को एनोटेट करना समझ में नहीं आता है।


सेवा परत में होना बेहतर है! इस लेख में से एक पर यह स्पष्ट रूप से समझाया गया है कि मैं कल आया था! यहां वह लिंक है जिसे आप चेक आउट कर सकते हैं!


@Repository सर्विस लेयर में उपयोग करता है जिसे नियंत्रक परत ( @Controller कंट्रोलर) और सेवा परत कॉल का उपयोग डीएओ परत ( @Repository ) यानी डेटा बेस से संबंधित ऑपरेशन में किया जाता है।


@Transactional एनोटेशन को उन सभी परिचालनों के आस-पास रखा जाना चाहिए जो अविभाज्य हैं। @Transactional लेनदेन प्रचार का उपयोग स्वचालित रूप से संभाला जाता है। इस मामले में यदि किसी अन्य विधि को वर्तमान विधि द्वारा बुलाया जाता है, तो उस विधि में चल रहे लेनदेन में शामिल होने का विकल्प होगा।

तो उदाहरण लें:

हमारे पास 2 मॉडल यानी Country और CityCountry और City मॉडल का रिलेशनल मैपिंग एक Country तरह कई शहरों में हो सकता है ताकि मैपिंग की तरह हो,

@OneToMany(fetch = FetchType.LAZY, mappedBy="country")
private Set<City> cities;

यहां देश ने कई शहरों में उन्हें Lazily लाने के साथ मैप किया। तो जब हम देश से ऑब्जेक्ट ऑब्जेक्ट को पुनर्प्राप्त करते हैं तो LAZILY भूमिका आती है तो हमें देश वस्तु के सभी डेटा मिलेंगे लेकिन शहरों का सेट नहीं मिलेगा क्योंकि हम शहरों को LAZILY ला रहे हैं।

//Without @Transactional
public Country getCountry(){
   Country country = countryRepository.getCountry();
   //After getting Country Object connection between countryRepository and database is Closed 
}

जब हम देश ऑब्जेक्ट से शहरों का सेट एक्सेस करना चाहते हैं तो हमें उस सेट में शून्य मान मिलेगा क्योंकि सेट की ऑब्जेक्ट केवल सेट को सेट किया गया है, सेट के मान प्राप्त करने के लिए डेटा को प्रारंभ नहीं किया गया है जिसका उपयोग हम @Transactional यानी,

//with @Transactional
@Transactional
public Country getCountry(){
   Country country = countryRepository.getCountry();
   //below when we initialize cities using object country so that directly communicate with database and retrieve all cities from database this happens just because of @Transactinal
   Object object = country.getCities().size();   
}

तो मूल रूप से @Transactional ट्रांसेक्शनल सेवा अंत बिंदु के साथ कनेक्शन बंद किए बिना एकल लेनदेन में एकाधिक कॉल कर सकती है।





dao