वसंत @ त्राटक - अलगाव, प्रचार


447

क्या कोई समझा सकता है कि वास्तविक दुनिया के उदाहरण के माध्यम से एनोटेशन में क्या अलगाव और प्रसार पैरामीटर हैं @Transactional?

मूल रूप से कब और क्यों मुझे उनके डिफ़ॉल्ट मूल्यों को बदलने के लिए चुनना चाहिए।

जवाबों:


442

अच्छा सवाल है, हालांकि जवाब देने के लिए एक तुच्छ नहीं।

प्रचार

परिभाषित करता है कि लेनदेन एक दूसरे से कैसे संबंधित हैं। सामान्य विकल्प:

  • Required: कोड हमेशा एक लेनदेन में चलेगा। एक नया लेनदेन बनाता है या उपलब्ध होने पर पुन: उपयोग करता है।
  • Requires_new: कोड हमेशा एक नए लेनदेन में चलेगा। यदि कोई मौजूद है, तो वर्तमान लेनदेन को निलंबित कर देता है।

एकांत

लेनदेन के बीच डेटा अनुबंध को परिभाषित करता है।

  • Read Uncommitted: गंदे पढ़ने की अनुमति देता है।
  • Read Committed: गंदे रीड्स की अनुमति नहीं देता है।
  • Repeatable Read: यदि एक ही लेन-देन में एक पंक्ति को दो बार पढ़ा जाता है, तो परिणाम हमेशा एक ही होगा।
  • Serializable: एक क्रम में सभी लेनदेन करता है।

विभिन्न स्तरों में बहु-थ्रेडेड अनुप्रयोग में अलग-अलग प्रदर्शन विशेषताएँ होती हैं। मुझे लगता है कि यदि आप dirty readsअवधारणा को समझते हैं तो आप एक अच्छे विकल्प का चयन करने में सक्षम होंगे।


गंदे पढ़े जाने का उदाहरण:

  thread 1   thread 2      
      |         |
    write(x)    |
      |         |
      |        read(x)
      |         |
    rollback    |
      v         v 
           value (x) is now dirty (incorrect)

तो एक डिफ़ॉल्ट डिफ़ॉल्ट (यदि ऐसा दावा किया जा सकता है) हो सकता है Read Committed, जो आपको केवल उन मूल्यों को पढ़ने देता है जो पहले से ही अन्य चल रहे लेनदेन द्वारा किए गए हैं, के प्रसार स्तर के साथ Required। तब आप वहां से काम कर सकते हैं यदि आपके आवेदन में अन्य आवश्यकताएं हैं।


एक व्यावहारिक उदाहरण जहां provideServiceदिनचर्या में प्रवेश करते समय एक नया लेनदेन हमेशा बनाया जाएगा और छोड़ने पर पूरा होगा:

public class FooService {
    private Repository repo1;
    private Repository repo2;

    @Transactional(propagation=Propagation.REQUIRES_NEW)
    public void provideService() {
        repo1.retrieveFoo();
        repo2.retrieveFoo();
    }
}

अगर हमने इस्तेमाल किया था Required, तो लेन-देन खुला रहेगा यदि दिनचर्या में प्रवेश करते समय लेनदेन पहले से ही खुला था। यह भी ध्यान दें कि एक परिणाम का परिणाम rollbackभिन्न हो सकता है क्योंकि कई निष्पादन एक ही लेनदेन में भाग ले सकते हैं।


हम परीक्षण के साथ व्यवहार को आसानी से सत्यापित कर सकते हैं और देख सकते हैं कि परिणाम प्रसार स्तर के साथ कैसे भिन्न होते हैं:

@RunWith(SpringJUnit4ClassRunner.class)
@ContextConfiguration(locations="classpath:/fooService.xml")
public class FooServiceTests {

    private @Autowired TransactionManager transactionManager;
    private @Autowired FooService fooService;

    @Test
    public void testProvideService() {
        TransactionStatus status = transactionManager.getTransaction(new DefaultTransactionDefinition());
        fooService.provideService();
        transactionManager.rollback(status);
        // assert repository values are unchanged ... 
}

के प्रसार स्तर के साथ

  • Requires new: हम उम्मीद करेंगे fooService.provideService()था नहीं वापस लुढ़का के बाद से यह बनाया यह अपना उप-लेन-देन है।

  • Required: हम उम्मीद करेंगे कि सब कुछ वापस लुढ़का हुआ था और बैकिंग स्टोर अपरिवर्तित था।


उस अंतिम लिंक का क्या संबंध है जिसके बारे में आप बात कर रहे हैं? लिंक किए गए डॉक्स के अनुसार, यह सत्र है जो यह बताता है कि वर्तमान लेनदेन क्या है, सत्र कारखाना नहीं।
डोनल फैलो

@ डॉनल, ओह सॉरी जो स्पष्ट नहीं था। मेरी बात यह थी कि चूंकि sessionFactory.getCurrentTransaction()जोड़ा गया था इसलिए HibernateTemplateलेन-देन के प्रबंधन के लिए अब और दौड़ने की कोई आवश्यकता नहीं है। मैंने इसे हटा दिया :)
जोहान Sjöberg

मेरा सवाल सिर्फ इस बारे में था कि लिंक कहां इंगित कर रहा था, वास्तव में। :-)
डोनाल्ड फेलो

वर्तमान लेनदेन में किए गए परिवर्तनों को कैसे प्राप्त
करें-

304

PROPAGATION_REQUIRED = 0 ; यदि DataSourceTransactionObject T1 पहले से ही Method M1 के लिए प्रारंभ हो गया है। यदि किसी अन्य विधि M2 ट्रांजेक्शन ऑब्जेक्ट के लिए आवश्यक है, तो कोई भी नया Transaction ऑब्जेक्ट नहीं बनाया गया है ।Same ऑब्जेक्ट T1 का उपयोग M2 के लिए किया जाता है।

PROPAGATION_MANDATORY = 2 ; विधि एक लेनदेन के भीतर चलना चाहिए। यदि कोई मौजूदा लेन-देन प्रगति में नहीं है, तो एक अपवाद फेंक दिया जाएगा

PROPAGATION_REQUIRES_NEW = 3 ; यदि DataSourceTransactionObject T1 पहले से ही विधि M1 के लिए शुरू किया गया है और यह प्रगति (M1 को क्रियान्वित कर रहा है)। यदि कोई अन्य विधि M2 शुरू होती है तो T1 को विधि M2 की अवधि के लिए निलंबित कर दिया जाता है। नए DataSourceTransactionObject T2 के लिए M2.M2 अपने लेनदेन के संदर्भ में चलाते हैं।

PROPAGATION_NOT_SUPPORTED = 4 ; यदि DataSourceTransactionObject T1 पहले से ही M M.I.If के लिए शुरू हो गया है, तो एक और विधि M2 समवर्ती रूप से चलाया जाता है। तब M2 को लेन-देन के संदर्भ में नहीं चलना चाहिए। टी 1 को एम 2 समाप्त होने तक निलंबित कर दिया जाता है।

PROPAGATION_NEVER = 5 ; लेनदेन के संदर्भ में कोई भी विधि नहीं चलती है।

एक अलगाव स्तर: यह इस बारे में है कि अन्य समवर्ती लेनदेन की गतिविधियों से कितना लेनदेन प्रभावित हो सकता है। यह एक सुसंगत स्थिति में कई तालिकाओं में डेटा को छोड़ने वाली एक निरंतरता का समर्थन करता है। इसमें डेटाबेस में लॉकिंग रो और / या टेबल शामिल हैं।

कई लेनदेन के साथ समस्या

परिदृश्य 1। यदि T1 लेनदेन तालिका A1 का डेटा पढ़ता है जो T2.If द्वारा दूसरे समवर्ती लेन-देन द्वारा लिखा गया था, तो T2 के रोलबैक होने पर, T1 द्वारा प्राप्त डेटा अमान्य है। एक a = 2 मूल डेटा है। I2 T1 a = पढ़ें। 1 जो T2.If T2 रोलबैक द्वारा लिखा गया था, तब एक = 1 को DB2 में a = 2 में रोलबैक किया जाएगा। लेकिन, अब T1 में = 1 है, लेकिन DB तालिका में इसे बदलकर = 2 कर दिया गया है।

परिदृश्य । यदि T1 लेनदेन तालिका A1 से डेटा पढ़ता है। तालिका A1 पर एक और समवर्ती लेनदेन (T2) अद्यतन डेटा। तब T1 द्वारा पढ़ा गया डेटा तालिका A1 से अलग है। क्योंकि T2 ने T1 पर डेटा अद्यतन किया है। a = 1 और T2 ने a = 2.Then a =! b को अद्यतन किया।

परिदृश्य 3। यदि T1 लेनदेन निश्चित संख्या में पंक्तियों के साथ तालिका A1 से डेटा पढ़ता है। यदि एक और समवर्ती लेनदेन (T2) तालिका A1 पर अधिक पंक्तियाँ सम्मिलित करता है। T1 द्वारा पढ़ी गई पंक्तियों की संख्या तालिका A1 पर पंक्तियों से भिन्न है

परिदृश्य 1 को डर्टी रीड कहा जाता है।

परिदृश्य 2 को गैर-दोहराने योग्य रीड कहा जाता है।

परिदृश्य 3 को प्रेत रीड कहा जाता है।

तो, आइसोलेशन स्तर का विस्तार होता है, जिसे परिदृश्य 1, परिदृश्य 2, परिदृश्य 3 को रोका जा सकता है। आप लॉकिंग को लागू करके पूर्ण अलगाव स्तर प्राप्त कर सकते हैं। यह समसामयिक रीड को रोक रहा है और होने से एक ही डेटा को लिखता है। लेकिन यह प्रदर्शन को प्रभावित करता है। अलगाव का स्तर आवेदन पर निर्भर करता है कि आवेदन को कितना अलगाव की आवश्यकता है।

ISOLATION_READ_UNCOMMITTED : उन परिवर्तनों को पढ़ने की अनुमति देता है जो अभी तक प्रतिबद्ध नहीं हैं। यह परिदृश्य 1, परिदृश्य 2, परिदृश्य 3 से पीड़ित है

ISOLATION_READ_COMMITTED : समवर्ती लेनदेन से पढ़ता है जो प्रतिबद्ध है। यह परिदृश्य 2 और परिदृश्य 3 से पीड़ित हो सकता है। क्योंकि अन्य लेनदेन डेटा को अपडेट कर रहे होंगे।

ISOLATION_REPEATABLE_READ : एक ही फ़ील्ड के एकाधिक रीड्स समान परिणाम प्राप्त करेंगे जब तक कि यह अपने आप बदल न जाए। यह परिदृश्य से पीड़ित हो सकता है 3. क्योंकि अन्य लेनदेन डेटा सम्मिलित कर सकते हैं

ISOLATION_SERIALIZABLE : परिदृश्य 1, परिदृश्य 2, परिदृश्य 3 कभी नहीं होता है। यह पूर्ण अलगाव है। इसमें पूर्ण लॉकिंग शामिल है। यह लॉकिंग के कारण प्रदर्शन को प्रभावित करता है।

आप परीक्षण का उपयोग कर सकते हैं

public class TransactionBehaviour {
   // set is either using xml Or annotation
    DataSourceTransactionManager manager=new DataSourceTransactionManager();
    SimpleTransactionStatus status=new SimpleTransactionStatus();
   ;


    public void beginTransaction()
    {
        DefaultTransactionDefinition Def = new DefaultTransactionDefinition();
        // overwrite default PROPAGATION_REQUIRED and ISOLATION_DEFAULT
        // set is either using xml Or annotation
        manager.setPropagationBehavior(XX);
        manager.setIsolationLevelName(XX);

        status = manager.getTransaction(Def);

    }

    public void commitTransaction()
    {


            if(status.isCompleted()){
                manager.commit(status);
        } 
    }

    public void rollbackTransaction()
    {

            if(!status.isCompleted()){
                manager.rollback(status);
        }
    }
    Main method{
        beginTransaction()
        M1();
        If error(){
            rollbackTransaction()
        }
         commitTransaction();
    }

}

आप अलगाव और प्रसार के लिए विभिन्न मूल्यों के साथ परिणाम डिबग और देख सकते हैं।


वर्तमान लेनदेन में किए गए परिवर्तनों को कैसे प्राप्त
करें-

2
अलगाव स्तर और प्रसार के बीच क्या बातचीत है ? यदि विधि 1 अलगाव स्तर के साथ एक लेनदेन शुरू करता है, तो कहें, READ_COMMITTED, और बाद में स्तर 2 को REPEATABLE_READ के साथ कॉल करता है, निश्चित रूप से विधि 2 को अपने स्वयं के, नए लेन-देन में निष्पादित किया जाना है, चाहे जो भी व्यवहार व्यवहार निर्दिष्ट करता हो (जैसे केवल आवश्यक है)?
कॉर्नेल मैसन

यह दिखाने के लिए वास्तव में देर हो चुकी है, लेकिन जब PROPAGATION_REQUIRES_NEW, T1 (जो M1 द्वारा उपयोग किया जाता है) में M1 में एक और नया कॉल हुआ तो क्या होगा? (कहते हैं M1.1)
टिम जेड।

115

प्रत्येक पैरामीटर के बारे में पर्याप्त व्याख्या अन्य उत्तरों द्वारा दी गई है; हालाँकि आपने वास्तविक दुनिया का उदाहरण पूछा है, यहाँ वह है जो विभिन्न प्रचार विकल्पों के उद्देश्य को स्पष्ट करता है :

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

/* Sign Up service */
@Service
@Transactional(Propagation=REQUIRED)
class SignUpService{
 ...
 void SignUp(User user){
    ...
    emailService.sendMail(User);
 }
}

/* E-Mail Service */
@Service
@Transactional(Propagation=REQUIRES_NEW)
class EmailService{
 ...
 void sendMail(User user){
  try{
     ... // Trying to send the e-mail
  }catch( Exception)
 }
}

आपने देखा होगा कि दूसरी सेवा प्रचार प्रकार REQUIRES_NEW की है और इसके अलावा संभावना है कि यह एक अपवाद (SMTP सर्वर, अमान्य ई-मेल या अन्य कारण) फेंकता है। आप शायद पूरी प्रक्रिया को रोल-बैक नहीं करना चाहते हैं, जैसे। डेटाबेस या अन्य चीजों से उपयोगकर्ता की जानकारी निकालना; इसलिए आप दूसरी सेवा को अलग लेन-देन में कहते हैं।

हमारे उदाहरण पर वापस, इस बार आप डेटाबेस सुरक्षा के बारे में चिंतित हैं, इसलिए आप अपने DAO वर्गों को इस तरह परिभाषित करते हैं:

/* User DAO */
@Transactional(Propagation=MANDATORY)
class UserDAO{
 // some CRUD methods
}

इसका मतलब यह है कि जब भी कोई DAO ऑब्जेक्ट, और इसलिए db तक एक संभावित पहुंच बनाई जाती है, तो हमें यह आश्वस्त करने की आवश्यकता है कि कॉल हमारी सेवाओं में से एक के अंदर से किया गया था, जिसका अर्थ है कि एक लाइव लेनदेन मौजूद होना चाहिए; अन्यथा एक अपवाद occurs.Therefore प्रचार प्रकार का है अनिवार्य


26
REQUIRES_NEW के लिए सही उदाहरण।
रवि थपलियाल

5
अच्छे खर्च! वैसे प्रचार के लिए डिफ़ॉल्ट क्या है? इसके अलावा और भी बेहतर होगा अगर आप इस तरह से अलगाव के लिए एक उदाहरण दे सकते हैं। बहुत बहुत धन्यवाद।
प्रकाश के

5
@PrakashK डिफ़ॉल्ट की आवश्यकता है। ( docs.spring.io/spring-framework/docs/current/javadoc-api/org/… )
ihebiheb

59

अलगाव स्तर यह परिभाषित करता है कि एक लेन-देन द्वारा कुछ डेटा रिपॉजिटरी में किए गए परिवर्तन अन्य समवर्ती लेनदेन को कैसे प्रभावित करते हैं, और यह भी कि कब और कैसे परिवर्तित डेटा अन्य लेनदेन के लिए उपलब्ध हो जाता है। जब हम स्प्रिंग फ्रेमवर्क का उपयोग करते हुए एक लेन-देन को परिभाषित करते हैं तो हम उस अलगाव स्तर को भी कॉन्फ़िगर करने में सक्षम होते हैं जो उसी लेनदेन को निष्पादित करेगा।

@Transactional(isolation=Isolation.READ_COMMITTED)
public void someTransactionalMethod(Object obj) {

}

READ_UNCOMMITTED आइसोलेशन स्तर बताता है कि एक लेनदेन उन डेटा को पढ़ सकता है जो अभी भी अन्य लेन-देन द्वारा अप्रयुक्त है।

READ_COMMITTED आइसोलेशन स्तर बताता है कि एक लेनदेन उस डेटा को नहीं पढ़ सकता है जो अभी तक अन्य लेनदेन द्वारा प्रतिबद्ध नहीं है।

REPEATABLE_READ आइसोलेशन स्तर बताता है कि यदि कोई लेन-देन डेटाबेस से एक रिकॉर्ड को कई बार पढ़ता है तो उन सभी रीडिंग ऑपरेशंस का परिणाम हमेशा समान होना चाहिए।

अनुक्रमिक पृथक्करण स्तर सभी अलगाव स्तरों का सबसे अधिक प्रतिबंधक है। लेन-देन को सभी स्तरों पर लॉकिंग के साथ निष्पादित किया जाता है (पढ़ें, रेंज और लॉकिंग लिखें) ताकि वे प्रकट हों जैसे कि उन्हें क्रमबद्ध तरीके से निष्पादित किया गया था।

प्रसार यह तय करने की क्षमता है कि व्यापार के तरीकों को तार्किक या भौतिक लेनदेन दोनों में कैसे समझाया जाना चाहिए।

स्प्रिंग रीक्वायर्ड व्यवहार का मतलब है कि यदि वर्तमान सेम विधि निष्पादन संदर्भ में पहले से ही खोला लेनदेन है तो उसी लेनदेन का उपयोग किया जाएगा।

REQUIRES_NEW व्यवहार का अर्थ है कि एक नया भौतिक लेनदेन हमेशा कंटेनर द्वारा बनाया जाएगा।

नेस्टेड व्यवहार समान भौतिक लेनदेन का उपयोग करने के लिए नेस्टेड स्प्रिंग लेनदेन को नेस्टेड बनाता है लेकिन नेस्टेड इनवोकेशन के बीच सेवपॉइंट सेट करता है इसलिए आंतरिक लेनदेन भी बाहरी लेनदेन से स्वतंत्र रूप से रोलबैक हो सकता है।

MANDATORY व्यवहार बताता है कि एक मौजूदा खोला लेनदेन पहले से मौजूद होना चाहिए। यदि कंटेनर द्वारा एक अपवाद नहीं फेंका जाएगा।

NEVER व्यवहार बताता है कि एक मौजूदा खोला लेनदेन पहले से मौजूद नहीं होना चाहिए। यदि कोई लेन-देन मौजूद है तो एक अपवाद कंटेनर द्वारा फेंक दिया जाएगा।

NOT_SUPPORTED व्यवहार किसी भी लेनदेन के दायरे के बाहर निष्पादित करेगा। यदि एक खुला लेनदेन पहले से मौजूद है तो उसे रोक दिया जाएगा।

समर्थन व्यवहार एक लेनदेन के दायरे में निष्पादित होगा यदि एक खोला लेनदेन पहले से मौजूद है। यदि पहले से खोला लेन-देन नहीं है, तो विधि वैसे भी निष्पादित होगी लेकिन गैर-लेन-देन के तरीके से।


4
यदि आप जोड़ सकते हैं कि कब कौन सा उपयोग करना है, तो यह अधिक फायदेमंद होगा।
कुमार मनीष

कुछ उदाहरण दीजिए, शुरुआती लोगों के लिए यह बहुत मददगार होगा
नाइटिन्सिडार

23

एक लेनदेन एक डेटाबेस के साथ काम की एक इकाई का प्रतिनिधित्व करता है।

स्प्रिंग TransactionDefinitionइंटरफ़ेस में जो स्प्रिंग-कम्प्लायंट ट्रांजैक्शन प्रॉपर्टीज़ को परिभाषित करता है। @Transactionalएनोटेशन एक विधि या वर्ग पर लेनदेन विशेषताओं का वर्णन करता है।

@Autowired
private TestDAO testDAO;

@Transactional(propagation=TransactionDefinition.PROPAGATION_REQUIRED,isolation=TransactionDefinition.ISOLATION_READ_UNCOMMITTED)
public void someTransactionalMethod(User user) {

  // Interact with testDAO

}

प्रसार (प्रजनन): अंतर लेनदेन संबंध के लिए उपयोग करता है। (जावा इंटर थ्रेड कम्युनिकेशन के अनुरूप)

+-------+---------------------------+------------------------------------------------------------------------------------------------------+
| value |        Propagation        |                                             Description                                              |
+-------+---------------------------+------------------------------------------------------------------------------------------------------+
|    -1 | TIMEOUT_DEFAULT           | Use the default timeout of the underlying transaction system, or none if timeouts are not supported. |
|     0 | PROPAGATION_REQUIRED      | Support a current transaction; create a new one if none exists.                                      |
|     1 | PROPAGATION_SUPPORTS      | Support a current transaction; execute non-transactionally if none exists.                           |
|     2 | PROPAGATION_MANDATORY     | Support a current transaction; throw an exception if no current transaction exists.                  |
|     3 | PROPAGATION_REQUIRES_NEW  | Create a new transaction, suspending the current transaction if one exists.                          |
|     4 | PROPAGATION_NOT_SUPPORTED | Do not support a current transaction; rather always execute non-transactionally.                     |
|     5 | PROPAGATION_NEVER         | Do not support a current transaction; throw an exception if a current transaction exists.            |
|     6 | PROPAGATION_NESTED        | Execute within a nested transaction if a current transaction exists.                                 |
+-------+---------------------------+------------------------------------------------------------------------------------------------------+

अलगाव: अलगाव, डेटाबेस लेनदेन के एसीआईडी ​​(एटोमिसिटी, संगति, अलगाव, स्थायित्व) गुणों में से एक है। अलगाव यह निर्धारित करता है कि लेन-देन की अखंडता अन्य उपयोगकर्ताओं और प्रणालियों को कैसे दिखाई देती है। यह रिसोर्स लॉकिंग अर्थात कंसीलर कंट्रोल के लिए उपयोग करता है, यह सुनिश्चित करें कि किसी दिए गए बिंदु पर केवल एक ही लेन-देन संसाधन तक पहुँच सकता है।

लॉकिंग धारणा: आइसोलेशन स्तर यह निर्धारित करता है कि लॉक किस अवधि के हैं।

+---------------------------+-------------------+-------------+-------------+------------------------+
| Isolation Level Mode      |  Read             |   Insert    |   Update    |       Lock Scope       |
+---------------------------+-------------------+-------------+-------------+------------------------+
| READ_UNCOMMITTED          |  uncommitted data | Allowed     | Allowed     | No Lock                |
| READ_COMMITTED (Default)  |   committed data  | Allowed     | Allowed     | Lock on Committed data |
| REPEATABLE_READ           |   committed data  | Allowed     | Not Allowed | Lock on block of table |
| SERIALIZABLE              |   committed data  | Not Allowed | Not Allowed | Lock on full table     |
+---------------------------+-------------------+-------------+-------------+------------------------+

पढ़ें धारणा: निम्नलिखित 3 प्रकार की प्रमुख समस्याएं होती हैं:

  • गंदा पढ़ता है : एक और tx (लेन-देन) से अप्रकाशित डेटा पढ़ता है।
  • गैर-दोहराने योग्य रीड : UPDATESएक और tx से प्रतिबद्ध पढ़ता है ।
  • प्रेत पढ़ता है : प्रतिबद्ध INSERTSऔर / या DELETESदूसरे tx से पढ़ता है

विभिन्न प्रकार के रीड्स के साथ अलगाव का स्तर:

+---------------------------+----------------+----------------------+----------------+
| Isolation Level Mode      |  Dirty reads   | Non-repeatable reads | Phantoms reads |
+---------------------------+----------------+----------------------+----------------+
| READ_UNCOMMITTED          | allows         | allows               | allows         |
| READ_COMMITTED (Default)  | prevents       | allows               | allows         |
| REPEATABLE_READ           | prevents       | prevents             | allows         |
| SERIALIZABLE              | prevents       | prevents             | prevents       |
+---------------------------+----------------+----------------------+----------------+

उदाहरण के लिए


20

आप लगभग कभी भी उपयोग नहीं करना चाहते हैं Read Uncommitedक्योंकि यह वास्तव में ACIDअनुपालन नहीं है । Read Commmitedएक अच्छी शुरुआत है। Repeatable Readशायद रिपोर्टिंग, रोलअप या एकत्रीकरण परिदृश्यों में ही आवश्यक है। ध्यान दें कि कई DBs, पोस्टग्रेज में शामिल हैं वास्तव में repeatable Read का समर्थन नहीं करते हैं, आपको Serializableइसके बजाय उपयोग करना होगा। Serializableउन चीजों के लिए उपयोगी है जिन्हें आप जानते हैं कि किसी भी चीज़ से पूरी तरह से स्वतंत्र होना चाहिए; इसे synchronizedजावा में पसंद करें । REQUIRES_NEWप्रसार के साथ हाथ से जाने योग्य है ।

मैं REQUIRESउन सभी कार्यों के लिए उपयोग करता हूं जो UPDATE या DELETE क्वेरी के साथ-साथ "सेवा" स्तर के कार्यों को चलाते हैं। DAO स्तर के फ़ंक्शंस के लिए, जो केवल SELECTs चलाते हैं, मैं उपयोग SUPPORTSकरता हूं जो एक TX में भाग लेगा यदि एक पहले से ही शुरू हो गया है (यानी एक सेवा फ़ंक्शन से कॉल किया जा रहा है)।


13

लेन-देन अलगाव और लेन-देन प्रसार हालांकि संबंधित हैं लेकिन स्पष्ट रूप से दो बहुत अलग अवधारणाएं हैं। दोनों ही मामलों में डिफॉल्ट ग्राहक लेन-देन घटक में या तो डिक्लेरेटिव ट्रांजेक्शन मैनेजमेंट या प्रोग्रामेटिक ट्रांजैक्शन मैनेजमेंट का उपयोग करके अनुकूलित किया जाता है । प्रत्येक अलगाव स्तरों और प्रसार विशेषताओं का विवरण नीचे संदर्भ लिंक में पाया जा सकता है।

लेन-देन अलगाव

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

लेन-देन का प्रसार

किसी भी अनुरोध / प्रसंस्करण के लिए एक उद्यम आवेदन में कई घटक हैं जो काम करने के लिए शामिल हैं। इस घटक में से कुछ एक लेनदेन की सीमाओं (प्रारंभ / अंत) को चिह्नित करते हैं जो संबंधित घटक में उपयोग किया जाएगा और यह उप घटक है। घटकों की इस लेन-देन की सीमा के लिए, लेन-देन का प्रसार निर्दिष्ट करता है कि संबंधित घटक लेन-देन में भाग लेगा या नहीं और यदि कॉलिंग घटक पहले से ही है या शुरू नहीं हुआ है तो क्या होता है। यह Java EE Transaction Attributes के समान है। यह आमतौर पर ग्राहक लेनदेन / कनेक्शन प्रबंधक द्वारा कार्यान्वित किया जाता है।

संदर्भ:


1
महान, एक जगह पर सभी जानकारी, लिंक बहुत मददगार हैं, धन्यवाद @Gladwin Burboz
नाइट्रसिडार

7

मैं चला हूं outerMethod, method_1और method_2अलग-अलग प्रचार मोड के साथ।

नीचे विभिन्न प्रसार मोड के लिए आउटपुट है।

  • बाहरी विधि

    @Transactional
    @Override
    public void outerMethod() {
        customerProfileDAO.method_1();
        iWorkflowDetailDao.method_2();
    }
  • Method_1

    @Transactional(propagation=Propagation.MANDATORY)
    public void method_1() {
        Session session = null;
        try {
            session = getSession();
            Temp entity = new Temp(0l, "XXX");
            session.save(entity);
            System.out.println("Method - 1 Id "+entity.getId());
        } finally {
            if (session != null && session.isOpen()) {
            }
        }
    }
  • Method_2

    @Transactional()
    @Override
    public void method_2() {
        Session session = null;
        try {
            session = getSession();
            Temp entity = new Temp(0l, "CCC");
            session.save(entity);
            int i = 1/0;
            System.out.println("Method - 2 Id "+entity.getId());
        } finally {
            if (session != null && session.isOpen()) {
            }
        }
    }
      • आउटरमैथोड - बिना लेन-देन के
      • Method_1 - प्रचार।
      • method_2 - केवल ट्रांजेक्शन एनोटेशन
      • आउटपुट: method_1 अपवाद को फेंक देगा जो कोई मौजूदा लेनदेन नहीं है
      • आउटरमैथोड - बिना लेन-देन के
      • method_1 - लेन-देन एनोटेशन
      • method_2 - प्रचार।
      • आउटपुट: method_2 अपवाद को फेंक देगा जो कि कोई मौजूदा लेनदेन नहीं है
      • आउटपुट: method_1 डेटाबेस में रिकॉर्ड बनाए रखेगा।
      • आउटरमैथोड - लेनदेन के साथ
      • method_1 - लेन-देन एनोटेशन
      • method_2 - प्रचार।
      • आउटपुट: method_2 डेटाबेस में रिकॉर्ड बनाए रखेगा।
      • आउटपुट: method_1 डेटाबेस में रिकॉर्ड बनाए रखेगा। - यहां मेन आउटर मौजूदा ट्रांजैक्शन का इस्तेमाल विधि 1 और 2 दोनों के लिए किया गया है
      • आउटरमैथोड - लेनदेन के साथ
      • Method_1 - प्रचार।
      • method_2 - केवल ट्रांजेक्शन एनोटेशन और अपवाद फेंकता है
      • आउटपुट: डेटाबेस में कोई रिकॉर्ड कायम नहीं है जिसका मतलब है कि रोलबैक किया गया।
      • आउटरमैथोड - लेनदेन के साथ
      • Method_1 - प्रचार .REQUIRES_NEW)
      • method_2 - प्रचार .REQUIRES_NEW) और 1/0 अपवाद फेंकता है
      • आउटपुट: method_2 अपवाद को फेंक देगा ताकि method_2 रिकॉर्ड कायम न रहे।
      • आउटपुट: method_1 डेटाबेस में रिकॉर्ड बनाए रखेगा।
      • आउटपुट: Method_1 के लिए कोई रोलबैक नहीं है

3

हम इसके लिए जोड़ सकते हैं:

@Transactional(readOnly = true)
public class Banking_CustomerService implements CustomerService {

    public Customer getDetail(String customername) {
        // do something
    }

    // these settings have precedence for this method
    @Transactional(readOnly = false, propagation = Propagation.REQUIRES_NEW)
    public void updateCustomer(Customer customer) {
        // do something
    }
}

1

आप इस तरह का उपयोग कर सकते हैं:

@Transactional(propagation = Propagation.REQUIRES_NEW)
public EventMessage<ModificaOperativitaRapporto> activate(EventMessage<ModificaOperativitaRapporto> eventMessage) {
//here some transaction related code
}

आप इस चीज़ का भी उपयोग कर सकते हैं:

public interface TransactionStatus extends SavepointManager {
    boolean isNewTransaction();
    boolean hasSavepoint();
    void setRollbackOnly();
    boolean isRollbackOnly();
    void flush();
    boolean isCompleted();
}
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.