@ ट्रांसट्रैशनल मेथड बिना किसी दूसरे तरीके के कॉलिंग?


89

मैंने एक सेवा वर्ग में एक विधि देखी है जिसे चिह्नित किया गया था @Transactional, लेकिन यह उसी वर्ग में कुछ अन्य विधियों को भी बुला रहा था जिन्हें चिह्नित नहीं किया गया था @Transactional

क्या इसका मतलब यह है कि अलग-अलग तरीकों से कॉल करने से एप्लिकेशन को DB से अलग कनेक्शन खोलने या माता-पिता के लेनदेन को निलंबित करने, आदि के कारण हो सकता है?

किसी भी एनोटेशन के बिना किसी विधि के लिए डिफ़ॉल्ट व्यवहार क्या है जिसे @Transactionalएनोटेशन के साथ किसी अन्य विधि द्वारा कहा जाता है ?

जवाबों:


119

जब आप @Transactionalकिसी लेन-देन ब्लॉक के बिना किसी विधि को कॉल करते हैं , तो पैरेंट ट्रांज़ेक्शन नई विधि के लिए जारी रहेगा। यह पैरेंट मेथड (के साथ @Transactional) से एक ही कनेक्शन का उपयोग करेगा और कॉल विधि में किए गए किसी भी अपवाद के बिना ( @Transactionalलेन-देन की परिभाषा में लेन-देन को रोलबैक करने का कारण होगा)।

यदि आप उसी उदाहरण के @Transactionalसाथ किसी विधि से एनोटेशन के साथ किसी विधि को कॉल करते हैं @Transactional, तो इन विधियों को लेन-देन व्यवहार को लेन-देन पर कोई प्रभाव नहीं पड़ेगा। लेकिन अगर आप किसी ट्रांजेक्शन डेफिनिशन वाली किसी अन्य विधि से ट्रांजैक्शन डेफिनिशन वाली विधि कहते हैं, और वे अलग-अलग उदाहरणों में हैं, तो कोड विधि में दिए गए कोड में बताई गई लेनदेन परिभाषाओं का पालन किया जाएगा।

आप अनुभाग में अधिक विवरण पा सकते हैं वसंत लेन-देन प्रलेखन की घोषणात्मक लेनदेन प्रबंधन

स्प्रिंग डिक्लेक्टिव ट्रांजेक्शन मॉडल AOP प्रॉक्सी का उपयोग करता है। इसलिए AOP प्रॉक्सी लेनदेन के निर्माण के लिए जिम्मेदार है। एओपी प्रॉक्सी केवल तभी सक्रिय होगा जब इंस्टेंस के तरीकों को उदाहरण के बाहर से बुलाया जाए।


कि वसंत डिफ़ॉल्ट व्यवहार है?
गोई

हाँ। यह डिफ़ॉल्ट व्यवहार है।
अरुण पी जॉनी

2
@ टोमसज़ हाँ। लेकिन यह भी उल्लेख किया जाना चाहिए कि किसी अन्य @Transactional विधि से कॉल की जाने वाली पद्धति पर लेनदेन के प्रसार को कोई प्रभाव नहीं पड़ेगा।
Fil

1
@ टॉमाज़, यही मेरे कहने का मतलब था will follow the transaction definitions given in the called method। लेकिन यदि कॉल उसी ऑब्जेक्ट उदाहरण से आती है तो इसका कोई प्रभाव नहीं पड़ेगा क्योंकि कॉल एनओपी प्रॉक्सिज़ के माध्यम से प्रचारित नहीं होगी जो लेनदेन के रखरखाव के लिए जिम्मेदार हैं।
अरुण पी जॉनी

5
@ फीलिप, यह पूरी तरह से सही नहीं है, यदि आप किसी विधि @Transactionalको किसी भिन्न ऑब्जेक्ट / इंस्टेंस से परिभाषा के साथ कॉल करते हैं, तो भले ही कॉलिंग विधि में एक अलग @Transactionalविशेषता हो, लेकिन कॉल की गई विधि इसे स्वयं लेनदेन परिभाषा का पालन करेगी।
अरुण पी जॉनी

24
  • क्या इसका मतलब यह है कि अलग-अलग तरीकों से कॉल करने से एप्लिकेशन को DB से अलग कनेक्शन खोलने या माता-पिता के लेन-देन, आदि को निलंबित करने का कारण बनता है?

यह एक प्रसार स्तर पर निर्भर करता है । यहां सभी संभावित स्तर मान दिए गए हैं ।

उदाहरण के लिए एक प्रसार स्तर NESTED है एक मौजूदा लेनदेन "निलंबित" होगा और एक नया लेनदेन बनाया जाएगा ( ध्यान दें: एक नेस्टेड लेनदेन का वास्तविक निर्माण केवल विशिष्ट लेनदेन प्रबंधकों पर काम करेगा )

  • किसी भी एनोटेशन के बिना एक विधि के लिए डिफ़ॉल्ट व्यवहार क्या है जो @Transactional एनोटेशन के साथ किसी अन्य विधि द्वारा कहा जाता है?

डिफ़ॉल्ट प्रसार स्तर (जिसे आप "व्यवहार" कहते हैं) आवश्यक है । यदि कोई "इनर" विधि कहा जाता है, उस पर एक @Transactionalएनोटेशन है (या एक्सएमएल के माध्यम से घोषणात्मक रूप से लेन-देन किया जाता है ), तो यह एक ही लेनदेन के भीतर निष्पादित होगा , उदाहरण के लिए "कुछ भी नया नहीं" बनाया जाता है।


NOT_SUPPORTED के उप-केंद्रों के बारे में क्या जिनके पास कोई एनोटेशन नहीं है? क्या यह NOT_Supported को विरासत में मिला है या क्या उन्होंने एक नया लेनदेन खोला है क्योंकि REQURED डिफ़ॉल्ट है? उदाहरण के लिए: f1.call () {f2 ()} एनोटेशन NOT_SUPPORTED के साथ f1 और f2 के लिए गैर।
डेव

8

@ ट्रांसेक्शनल लेन-देन सीमा (आरंभ / अंत) को चिह्नित करता है, लेकिन लेनदेन स्वयं थ्रेड के लिए बाध्य है। एक बार जब कोई लेन-देन शुरू होता है, तो यह विधि कॉल के दौरान तब तक प्रचारित होता है जब तक कि मूल विधि वापस नहीं आ जाती है और लेनदेन वापस शुरू हो जाता है।

यदि किसी अन्य विधि को @Transactional एनोटेशन कहा जाता है, तो प्रचार उस एनोटेशन के प्रसार विशेषता पर निर्भर करता है।


3 कुछ डिग्री में एक दूसरे के साथ संघर्ष का जवाब देते हैं, निश्चित नहीं है कि कौन अधिक सटीक है।
user218867

1
@EricWang बस साझा करने के लिए करना चाहता था कि मैं इस परिदृश्य आज और से जवाब बाहर का परीक्षण किया अरुण पी जॉनी (टिप्पणी के साथ) की इस स्थिति के लिए सबसे सही है आंतरिक आमंत्रण।
विनय विष्ट

3

यदि आंतरिक विधि को @ विधि के साथ एनोटेट नहीं किया गया है, तो आंतरिक विधि बाहरी विधि को प्रभावित करेगी।

मामले में आंतरिक विधि के साथ @ टिप्पणी के साथ भी टिप्पणी की जाती है REQUIRES_NEW, निम्नलिखित होगा।

...
@Autowired
private TestDAO testDAO;

@Autowired
private SomeBean someBean;

@Override
@Transactional(propagation=Propagation.REQUIRED)
public void outerMethod(User user) {
  testDAO.insertUser(user);
  try{
    someBean.innerMethod();
  } catch(RuntimeException e){
    // handle exception
  }
}


@Override
@Transactional(propagation=Propagation.REQUIRES_NEW)
public void innerMethod() {
  throw new RuntimeException("Rollback this transaction!");
}

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


1
शुरुआती लोगों के लिए स्पष्ट करने के लिए, मुझे पूरा यकीन है कि इनरमेथोड () की तुलना में इनरमेथोड () एक अलग बीन (उर्फ स्प्रिंग-प्रबंधित जावा ऑब्जेक्ट) पर होना चाहिए। यदि वे दोनों एक ही बीन पर हैं, तो मुझे नहीं लगता कि इनमेमेथोड वास्तव में अपने एनोटेशन में घोषित व्यवहार व्यवहार का उपयोग करेगा। बल्कि बाहरीमेथोड () घोषणा में जो घोषित किया गया है उसका उपयोग करेगा। इस की वजह से कैसे स्प्रिंग AOP है, जो इसे का @Transactional एनोटेशन के लिए प्रयोग किया जाता है (संभालती है docs.spring.io/spring/docs/3.0.x/spring-framework-reference/... )
johnsimer
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.