java - अवरोधन लेनदेन केवल तभी किया जाता है जब प्रतिबद्ध हो जाता है लेकिन पहले प्रतिबद्ध है




spring jpa (2)

आपका मामला यह है कि आपके संसाधन में से एक दो-चरण-कमिट के साथ संगत नहीं है ( XA- सक्षम नहीं ) आपका विचार अनुच्छेद XA और http://www.javaworld.com/article/2077963/open-source-tools/distributed-transactions-in-spring--with- के अंतिम संसाधन Gambit में वर्णित पैटर्न की दिशा में जाता है और-बिना-xa.html

स्प्रिंग बूट + बिट्रॉनिक्स + गैर एक्सए डेटास्त्र्र + एक्सए जेएमएस कनेक्शन सेट अप करने के तरीके के जवाब में अंतिम संसाधन जुम्बिट का उपयोग संक्षिप्त रूप से समझाया गया है

वैसे, आपका प्रश्न यह उल्लेख नहीं करता है कि आप किस लेनदेन प्रबंधक का उपयोग करते हैं (जेबोस, बिट्रॉनिक्स जेटीए, परमाणुकोस लेनदेन आवश्यक, ...)

संदर्भ जावा है - हाइबरनेट और स्प्रिंग के साथ जेपीए।

चलो दो चरण प्रतिबद्ध प्रोटोकॉल का परिदृश्य लेते हैं (लेकिन केवल एक संसाधन के साथ):

  1. आवेदन से प्रतिबद्ध करने के लिए प्रश्न

  2. मत हाँ / नहीं (हमारे मामले में डेटाबेस से)

3.1। यदि हां, तो डेटाबेस से

3.1.1। ( कॉलबैक कोड को करें ) - प्रोटोकॉल का हिस्सा नहीं है

3.1.2। डेटाबेस के लिए प्रतिबद्ध

3.2 यदि नहीं,

3.2.1 डेटाबेस में रोलबैक

जो मैं चाहता हूँ वह कॉलबैक 3.1.1 से कोड में करने का एक तरीका है, लेकिन केवल जब यह ज्ञात हो जाता है कि लेनदेन किया जाएगा, लेकिन इससे पहले वास्तव में प्रतिबद्ध है। इसके अलावा, यदि कोई अपवाद यहां फेंक दिया गया है, तो लेन-देन को लुढ़का हुआ होना चाहिए।

स्प्रिंग से TransactionSynchronization (*) का उपयोग करने से, इससे पहले कि वह प्रतिबद्ध / पूर्ण हो गया है या उसके बाद / पूर्ण किया गया था, आपको लेनदेन को रोकना पड़ता है

  • beforeCommit() कॉलबैक का कहना है कि विधि के बाद एक रोलबैक तब भी हो सकता है;
  • beforeComplete() कहा जाता है, भले ही लेनदेन असफल हो
  • afterCommit/Complete() को लेनदेन के बाद कहा जाता है वास्तव में डेटाबेस के लिए प्रतिबद्ध है और रोलबैक करने का कोई तरीका नहीं है।

अब जब मुझे लगता है कि ऐसा लगता है कि मैं जो चाहता हूं, एक और दो-चरण प्रोटोकॉल प्रतिबद्ध है; लेकिन मैं सोच रहा हूँ कि क्या वसंत में एक वैकल्पिक हल है। अंतर यही है कि कॉलबैक में किया गया कॉल वापस नहीं लाया जा सकता।

(*) स्प्रिंग 4.2 से @TransactionalEventListener और TransactionPhase @TransactionalEventListener साथ बहुत आसान है, जो अच्छी तरह से @TransactionalEventListener


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

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

संपादित करें: मुझे लगता है कि एक सादृश्य अच्छा होगा

मामला 1: लेन-देन का क्लासिक उदाहरण दुकान में एक केला खरीद रहा है, अगर आपके पास कोई पैसा नहीं है, या स्टोर में कोई केला नहीं है, स्टोर पैसे नहीं मिल रहा है, आप केरल नहीं मिलते हैं, यह आम तौर पर है हो जाता। लेकिन अगर सभी स्थितियां सेट की जाती हैं तो लेनदेन सफलतापूर्वक कम होगा।

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

अगर आप पहले मामले पर वापस जाते हैं, तो आप देख सकते हैं कि आपके पास पैसा है, स्टोर में एक केला है, स्टोर को अपना पैसा दें, सभी ग्राहकों को फेंक दें, स्टोर में दरवाजे लॉक करें ताकि स्टोर एक अपरिवर्तनीय स्थिति में हो। अपनी विधि करो, जो आप रोलबैक नहीं कर सकते, स्टोर पर वापस आकर और केला ले सकते हैं। कोई भी आपको आश्वासन दे सकता है कि केला अभी भी वहां होगा, लेकिन यह बहुत संभावना है।