2015-08-26 7 views
5

मुझे समझ में नहीं आ रहा है कि ईजेबी कंटेनर @Stateless बीन्स के लिए उदाहरण चर के साथ थ्रेड-सुरक्षा का प्रबंधन कैसे करता है। तो मैं एक साधारण उदाहरण दे देंगे से पहले मेरी चिंताओं को समझा: मेरे सवालोंईजेबी पूलिंग बनाम थ्रेड-सुरक्षित और @PreDestroy

@Stateless 
public class BeanTest{ 

@Inject 
private String var; 

private Connection connection; 

@Resource(name = "jdbc/TestDB") 
private DataSource dataSource; 

public void modify() { 
    var = "TestName"; 
} 

@PostConstruct 
public void initialize() { 
    try { 
     connection = dataSource.getConnection(); 
    } catch (SQLException sqle) { 
     sqle.printStackTrace(); 
    } 
} 

@PreDestroy 
public void cleanup() { 
    try { 
     connection.close(); 
     connection = null; 
    } catch (SQLException sqle) { 
     sqle.printStackTrace(); 
    } 
} 
} 

यहाँ है, यह सोचते हैं कि हमारे कंटेनर पूलिंग का समर्थन करता है:

1. पूलिंग बनाम थ्रेड-सुरक्षित:

उपयोगकर्ता 1 ने BeanTest का एक उदाहरण इस्तेमाल किया और संशोधित विधि का उपयोग करके var संशोधित किया, फिर वह समाप्त हो गया और कंटेनर ने प्रबंधित पूल में BeanTest का उदाहरण दिया। जब उपयोगकर्ता 2 अनुरोध के लिए एक ही बीन का उपयोग करने का प्रयास करता है, तो वह BeanTest का एक ही उदाहरण प्राप्त कर सकता है जिसे उपयोगकर्ता 1 द्वारा आंशिक रूप से संशोधित किया गया है (मुझे समझ में आता है कि एक और उदाहरण भी मिल सकता है)। तो इंस्टेंस वेरिएबल var का कौन सा राज्य वह पाएगा (डिफ़ॉल्ट मान जो null या "TestName" है)? यदि यह नया संशोधित है, तो क्या इसका मतलब यह है कि @Stateless बीन्स 100% थ्रेड-सुरक्षित नहीं हैं? तो finnaly कोई कंटेनर -value धागा सुरक्षा के संबंध में, जोड़ा जाता है उदाहरण चर का उपयोग नहीं कर के रूप में एक सेम धागा सुरक्षित भले ही वह किसी @Stateless सेम

2. पूलिंग @PreDestroy बनाम

नहीं है सेम है बनाता है प्रबंधित पूल में लौट आया और नष्ट नहीं हुआ, क्या इसका मतलब यह है कि @Predestroy विधि नहीं बुलाया जाएगा और उस स्थिति में कनेक्शन खोला जाएगा? तो, अगर हमारे पास पूल में उस बीन का 30 इंच है, तो हमारे पास 30 खुले कनेक्शन हो सकते हैं जिनका उपयोग नहीं किया जाता है, क्या यह प्रदर्शन समस्या नहीं है? या यह नहीं @Predestroy पूलिंग के साथ काम कर रहा है? (Connection का उपयोग कर एक उदाहरण मात्र है, हम है कि हम @Predestroy में बंद करने की आवश्यकता ressource अन्य प्रकार हो सकता है)

एनबी:यह एक वास्तविक जीवन उदाहरण नहीं है तो I'am कोई वैकल्पिक समाधान की तलाश में नहीं , मेरी चिंता का विषय पूरी अवधारणा को समझने के लिए है और कैसे चीजें अनुप्रयोग सर्वर में प्रबंधित कर रहे हैं, क्या हुड

+0

आपकी चिंताएं ठीक हैं, जब भी मैं कर सकता हूं मैंने ईजेबी से स्पष्ट किया है। वसंत के साथ आपको इतना बकवास, बीमार परिभाषित अर्थशास्त्र नहीं मिलेगा। –

+0

क्या आपको 'स्टेटलेस 'के बजाय' @ स्टेटफुल' का उपयोग करना चाहिए? –

+0

इसके अलावा, जब भी आपको एक की आवश्यकता होती है, तो आपको कनेक्शन प्राप्त करना चाहिए, जब ईजेबी प्रारंभ नहीं होता है। –

उत्तर

2

मुझे लगता है कि थ्रेड-सुरक्षा की बात कर रहे गैर reenterant खंड

है कंटेनर प्रदाता के दायित्व उद्यम JavaBeans 3.2, अंतिम रिलीज सत्र बीन घटक अनुबंध अप्रैल 10, 2013 2: 5 9 बजे ओरेकल

4.10.13 गैर-पुनर्विक्रेता उदाहरण कंटेनर को यह सुनिश्चित करना चाहिए कि ly एक थ्रेड पर किसी भी समय एक बेकार या राज्यव्यापी सत्र बीन उदाहरण निष्पादित किया जा सकता है। इसलिए, स्टेटफ उल और स्टेटलेस सत्र बीन्स को पुनर्विक्रेता के रूप में कोडित करने की आवश्यकता नहीं है। इस नियम में से एक निहितार्थ यह है कि एक आवेदन Nnot, एक राज्यविहीन या स्टेटफुल सत्र सेम उदाहरण

आप एक राज्यविहीन सत्र सेम में, EJB प्रोग्रामिंग प्रतिबंध की अनदेखी कर सकता है लूपबैक कॉल कर ca और धागे का एक समूह बनाने के है कुछ गैर थ्रेड सुरक्षित करें। कंटेनर आपको रोक नहीं देगा। थ्रेड प्रबंधन विवादों के कारण यह सभी प्रकार की त्रुटियों का कारण बन सकता है।

कंटेनर केवल वादा करता है कि यह केवल एक समय में स्टेटलेस ईजेबी तक 1 थ्रेड पहुंच की अनुमति देगा। (सिंगलेट्स के आसपास कुछ अलग नियम हैं)

आप सही हैं, अगर उदाहरण पूल में लौटाए जाते हैं कि आपके उदाहरण में कनेक्शन बना सकते हैं। क्योंकि निश्चित रूप से उदाहरण अभी भी मौजूद है।

यदि आप ऐप सर्वर डॉक्स, यानी ग्लासफ़िश ईजेबी पूल ट्यूनिंग अध्याय में खोदते हैं, तो आप पाएंगे कि डिफ़ॉल्ट रूप से पूल पर लौटने के बजाय ऑब्जेक्ट इंस्टेंस को नष्ट करना डिफ़ॉल्ट है। जेडीबीसी कनेक्शन के साथ, जो बंद और साफ हो जाएगा। पुन: उपयोग एक विकल्प है, यदि आप एसएसबी में राज्य बनाने का प्रयास करते हैं तो आप कुछ अतिरिक्त मेमोरी का उपभोग कर सकते हैं। मुझे नहीं लगता कि अगर पूल में निष्क्रिय बैठे हैं तो बहुत अधिक प्रदर्शन प्रभाव पड़ता है।

सटीक पूलिंग कार्यान्वयन एप्लिकेशन सर्वर विक्रेता तक है, जब तक वे spec का पालन करते हैं। मुझे लगता है कि आप उपयोग के बाद उदाहरण को नष्ट करना डिफ़ॉल्ट व्यवहार पाएंगे। जो प्रबंधित संसाधनों को साफ करने का कारण बनता है।

लेकिन यह सब एक प्रकार का म्यूट है, उदाहरण में आप कक्षा में एक राज्य, कनेक्शन क्षेत्र को स्टोर करने की कोशिश कर रहे हैं। एक स्टेटलेस घटक में राज्य बनाने की कोई आवश्यकता नहीं है, यह इस प्रकार का घटक नहीं है। जावा ईई आर्किटेक्चर हैंडल राज्य के अन्य हिस्सों। (संस्थाएं, स्टेटफुलबीन, जेसीए)

+0

आपके अक्षयकरण के लिए धन्यवाद। तो फिर से शुरू करने के लिए, एनोटेशन '@ स्टेटलेस 'का बीन स्टेटलेस बनाने पर कोई प्रभाव नहीं पड़ता है (मुझे पता है कि इसमें अन्य प्रभाव हैं: कंटेनर द्वारा प्रबंधित, लेनदेन जैसी सेवाओं का उपयोग करें ...)? यह डेवलपर है जो इंस्टेंस वैरिएबल का उपयोग न करके इसे स्टेटलेस बनाता है ... – Tarik

+0

हां, @ स्टेटलेस यह है कि आप एप्लिकेशन सर्वर को कैसे बताते हैं, यह एक स्टेटलेस बीन है। एप्लिकेशन सर्वर पर भरोसा है कि आपने जो भी लिखा है वह वास्तव में आप क्या करना चाहते हैं। – Chris

1
  1. इंजेक्शन AnotherBean तो है राज्यविहीन, तो यह AnotherBean.setName() कॉल करने के लिए कोई मतलब नहीं है के तहत हो रहा है। यदि यह राज्यपूर्ण है, तो यह एक स्टेटलेस बीन को एक स्टेटलेस में इंजेक्ट करने का एहसास नहीं है (जांचें कि किस राज्य के बीन्स बने हैं)। थ्रेड-सुरक्षा के बारे में: कंटेनर आपके वर्गों को स्वयं सुरक्षित नहीं कर सकता है, लेकिन यह गारंटी देता है कि एक क्लाइंट थ्रेड एक समय में एक निश्चित ईजेबी उदाहरण का उपयोग करेगा (क्रिस के उत्तर से उद्धरण की जांच करें)। इसलिए, यदि आप अपने ईजेबी क्लाइंट में विभिन्न धागे में ईजेबी का उपयोग नहीं करते हैं, तो कोड thread confinment का उपयोग करके थ्रेड-सुरक्षित है।
  2. एक स्टेटलेस बीन में अन्य इंजेक्शन वाले इंस्टेंस चर का उपयोग न करें। अन्यथा आप अपने @Stateful एनोटेशन के अनुरूप नहीं हैं। तो, connection राज्य चर हटा दें। वैसे भी, आप केवल अपने बीन के लिए लंबे समय तक खुला कनेक्शन नहीं रखना चाहते हैं: इसे डेटासोर्स से हर बार प्राप्त करें। इसके बाद कनेक्शन को बंद करने के लिए भी न भूलें (कोशिश/अंत में खंड में)। पूलिंग के साथ, यह एक जेडीबीसी कनेक्शन पूल की तरह काम करता है: जब पूल/ईजेबी कंटेनर निर्णय लेता है तो उसे अब उदाहरण की आवश्यकता नहीं होती है (उदाहरण के लिए जब यह उदाहरणों की संख्या को कम करना चाहता है या जब कोई application exception फेंक दिया जाता है), तो @PreDestroy विधि wil बुलाया जाए।
+0

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

+0

दूसरे उत्तर के लिए, कनेक्शन सिर्फ एक उदाहरण है, क्या मुझे समझने की जरूरत है कि हुड के नीचे क्या होता है? कैसे @Predestroy पूलिंग के साथ काम करते हैं? – Tarik

+0

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

2

1) कंटेनर थ्रेड सुरक्षा की गारंटी देता है जिसका अर्थ है कि एक ही धागा एक समय में दिए गए एसएलएसबी तक पहुंच सकता है। इसकी गारंटी के साथ इसका कोई लेना-देना नहीं है कि राज्य नहीं बदला जाएगा। बीटीडब्लू म्यूटेबल एसएलएसबी के अंदर राज्य का कोई मतलब नहीं है।

2) आप एसएलएसबी के जीवनकाल के दौरान कनेक्शन नहीं रखना चाहते हैं क्योंकि आप इसे थकावट के जोखिम वाले पूल पर लौटने से प्रभावी ढंग से रोक रहे हैं।

+0

के लिए मैं दूसरी बिंदु को समझ नहीं पाया , लेकिन आप पहले के बारे में सही हैं। हालांकि, मुझे यह समझ में आया कि कंटेनर भी स्टेटलेसनेस की गारंटी नहीं देता है, लेकिन यह इफेक्ट चर – Tarik

+0

का उपयोग न करके डेवलपर है, यदि ऐप सर्वर पूलिंग कर रहा है या नहीं, तो एसएलएसबी इंस्टेंस, प्रीडेस्ट्राय विधि को वापस लौटने पर कॉल नहीं किया जा सकता है तालाब। इसका मतलब है कि कनेक्शन कनेक्शन पूल में वापस नहीं आ रहा है। यदि आप अपने मैक्सकनेक्शन तक पहुंचते हैं तो आप एक नया कनेक्शन प्राप्त करने का प्रयास करते समय अनिश्चित काल तक प्रतीक्षा कर सकते हैं। – Franck

+0

आपकी स्पष्टीकरण के लिए धन्यवाद फ्रैंक – Tarik

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