2017-10-27 14 views
5

जैसा कि मैं इसे समझता हूं, सभी लेन-देन थ्रेड-बाउंड होते हैं (यानी थ्रेडलोकल में संग्रहीत संदर्भ के साथ)। उदाहरण के लिए यदि:एकाधिक धागे समाधान में एकल लेनदेन

  1. मैं एक व्यवहार माता पिता विधि में कोई लेनदेन शुरू
  2. एक अतुल्यकालिक कॉल में
  3. मेक डेटाबेस डालने # 1
  4. एक और अतुल्यकालिक कॉल में
  5. मेक डेटाबेस डालने # 2

फिर जो दो अलग-अलग लेन-देन (प्रत्येक डालने के लिए एक) उत्पन्न करेगा, भले ही उन्होंने एक ही "लेनदेन" माता-पिता को साझा किया हो।

उदाहरण के लिए, मान लीजिए कि मैं दो आवेषण प्रदर्शन करते हैं (और एक बहुत ही सरल नमूना का उपयोग कर, एक प्रबंधक या संक्षिप्तता के लिए completable भविष्य, आदि का उपयोग नहीं कर आईई):

@Transactional 
public void addInTransactionWithAnnotation() { 
    addNewRow(); 
    addNewRow(); 
} 

दोनों आवेषण प्रदर्शन करेंगे, के रूप में वांछित , एक ही लेनदेन के हिस्से के रूप में।

हालांकि, अगर मैं प्रदर्शन के लिए उन आवेषण parallelize करना चाहता था:

@Transactional 
public void addInTransactionWithAnnotation() { 
    new Thread(this::addNewRow).start(); 
    new Thread(this::addNewRow).start(); 
} 

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

मुख्य प्रश्न: क्या बच्चे के धागे को लेनदेन को सुरक्षित रूप से प्रसारित करने का कोई तरीका है?

केवल समाधान मैं इस समस्या को हल करने के बारे में सोचा गया है:

  1. उपयोग JTA या कुछ XA प्रबंधक, जो परिभाषा द्वारा यह करने के लिए सक्षम होना चाहिए। हालांकि, मैं आदर्श रूप से अपने समाधान के लिए XA का उपयोग नहीं करना चाहता क्योंकि इसकी ओवरहेड
  2. मेरे द्वारा किए गए सभी लेनदेन कार्यों को पाइप करें (उपर्युक्त उदाहरण में, addNewRow() फ़ंक्शन) एक ही थ्रेड पर, और सभी बहुप्रचारित फैशन में पूर्व कार्य।
  3. लेनदेन की स्थिति पर इनहेरटेबल थ्रेडलोकल का लाभ उठाने के लिए कुछ तरीके का पता लगाना और इसे बच्चों के धागे में प्रचारित करना। मुझे यकीन नहीं है कि यह कैसे करें।

कुछ और ऐसे समाधान संभव हैं? भले ही यह एक कामकाज की तरह थोड़ा स्वाद लेता है (जैसे ऊपर मेरे समाधान)?

उत्तर

2

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

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

आखिरकार, कार्यकर्ता धागे को काम करने के लिए काम करने का मतलब यह नहीं है कि आपके पास एक कार्यकर्ता धागा होना चाहिए, आपके पास श्रमिकों का एक पूल हो सकता है और कुछ समानांतरता प्राप्त हो सकती है यदि यह आपके आवेदन के लिए वास्तव में फायदेमंद है। निर्माता/उपभोक्ताओं के संदर्भ में सोचें।

+0

कार्यबल धागे को व्यवहार्य समाधान के रूप में पुष्टि करने के लिए धन्यवाद। क्या आप इस समाधान को लागू करने के तरीके पर थोड़ा और प्रकाश डालने पर ध्यान देते हैं? अधिक विशेष रूप से; अगर वह धागा उस कामकाज का हिस्सा बनने के लिए अधिक काम के लिए मतदान करेगा, तो यह कब पता चलेगा कि कब पूरा करना है? इसके अतिरिक्त, यह वास्तव में वर्तमान लेनदेन को पूरा करने के लिए कैसे आगे बढ़ेगा जो इसे पहले से शुरू हो चुका है और तैयार होने पर इसे शुरू करने के लिए तैयार रहें? – Dovmo

+0

आप निम्नलिखित उदाहरण का अध्ययन करके शुरू कर सकते हैं http://javarevisited.blogspot.com.es/2012/02/producer-consumer-design-pattern-with.html?m=1 – gpeche

1

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

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

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

सामान्य रूप से यह अमाहल के कानून में उबाल जाता है। यदि डीबी I/O काम साझा करने के लिए एकाधिक समवर्ती थ्रेडों को अनुमति देने के लिए आपको प्रति कनेक्शन एकाधिक कनेक्शन का उपयोग करने से प्राप्त गति प्राप्त होती है, तो आप बैचिंग से प्राप्त होने वाले चीज़ों के सापेक्ष बड़े होते हैं, फिर एक्सए का ओवरहेड सार्थक होता है। यदि गति गणना स्थानीय गणना में है और डीबी I/O एक मामूली चिंता है, तो एक थ्रेड जो जेडीबीसी कनेक्शन को नियंत्रित करता है और थ्रेड पूल में गैर-आईओ गणना कार्य ऑफ़लोड करता है, वह रास्ता है।

संबंधित मुद्दे