2013-12-13 9 views
11

मैं कुछ आरामपूर्ण एपीआई विकास के लिए जेएक्स-आरएस का उपयोग करना सीख रहा हूं और मेरे संसाधन वर्गों के बारे में कोई समस्या है।@ स्टेटलेस बनाम @RequestScoped

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

यदि मैं अपनी संसाधन कक्षा को स्टेटलेस बनने के लिए बदलता हूं तो सब ठीक है और इकाई प्रबंधक किसी भी मुद्दे के बिना जारी रह सकता है।

मैं अभी भी जावाईई के लिए नया हूं और यह जानना चाहता हूं कि ऐसा क्यों होता है और @ स्टेटलेस एनोटेशन क्या करता है जो दृढ़ता संदर्भ को सही ढंग से इंजेक्ट करने की अनुमति देता है। मैं यह भी जानना चाहूंगा कि जेएक्स-आरएस संसाधन वर्गों के साथ RequestScoped की बजाय स्टेटलेस होने में कोई समस्या है या नहीं, क्योंकि मैंने देखा है कि अधिकांश ट्यूटोरियल हैं।

मैंने चित्रण के लिए नीचे कुछ उदाहरण कोड शामिल किया है।

@Path("Things") 
//@Stateless //works just fine when em.persist() is called 
@RequestScoped //throws transactionrequiredexception when em.persist() is called 
public class ThingsResource{ 

    @PersistenceContext(unitName = "persistenceUnitName") 
    EntityManager em; 


    public ThingsResource() { } 

    @POST 
    @Produces(MediaType.APPLICATION_JSON) 
    public Response postThing(ThingDTO thing){ 

     ThingEntity newThing = new ThingEntity(thing); 
     em.persist(newThing); 
     em.flush(); 

     return Response.created(new URI("/" + newThing.getId()).build(); 

    } 
} 
+4

मुझे लगता है कि अगर आप एक स्टेटलेस बीन है और आप लेन-देन एनोटेशन, उदा (आवश्यक) का उपयोग नहीं है, अपने Applicationserver अपने EJBs के लिए कंटेनर आधारित लेन-देन का उपयोग करने के लिए जा रहा है। अनुरोध स्कोप्ड बीन्स सर्वलेट कंटेनर के भीतर हैं जो कंटेनर आधारित लेनदेन प्रदान नहीं करता है (मुझे लगता है) –

उत्तर

8

मैथियस स्पॉट पर है।

ए @ स्टेटलेस एनोटेटेड बीन एक ईजेबी है जो डिफ़ॉल्ट रूप से Container-Managed-Transactions प्रदान करता है। यदि ईजेबी के ग्राहक ने एक प्रदान नहीं किया है तो सीएमटी डिफ़ॉल्ट रूप से एक नया लेनदेन तैयार करेगा।

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

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

हाल जावा-ee-7 jax-रु पर tuturial में Oracle EJBs का उपयोग कर (@Stateless) का उदाहरण है।

... EJB के @ javax.ejb.Asynchronous एनोटेशन और @Suspended AsyncResponse के संयोजन रुचि ग्राहक की अंतिम अधिसूचना के साथ व्यापार तर्क की अतुल्यकालिक निष्पादन सक्षम बनाता है। किसी भी JAX-आरएस जड़ संसाधन @Stateless या @Singleton एनोटेशन के साथ टिप्पणी की जा सकती है और कर सकते हैं, प्रभाव में, एक EJB के रूप में कार्य ..

इस परिदृश्य में बनाम @Stateless @RequestScoped के बीच मुख्य अंतर यह होगा कि कंटेनर ईजेबी को पूल कर सकता है और कुछ महंगे निर्माण/नष्ट संचालन से बच सकता है जो कि बीन्स के लिए आवश्यक हो सकता है जो हर अनुरोध पर अन्यथा बनाया जाएगा।

+0

तो बेथर क्या है या प्रदर्शन के संबंध में अधिक कुशल क्या है? यह @ स्टेटलेस होना चाहिए क्योंकि यह पूल योग्य है, है ना? इसका पुनर्विक्रय पर कौन सी कमी है? - अगर आप इस पहलू को आपके उत्तर में शामिल कर सकते हैं तो मुझे खुशी होगी - धन्यवाद! मैं पहले ही अग्रिम में मतदान कर चुका हूं ... :) – badera

+0

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

2

जब आप अपने रूट संसाधन को ईजेबी (@Stateless के साथ एनोटेट करके) बनाना नहीं चाहते हैं, तो आप UserTransaction का उपयोग कर सकते हैं।

@Path("/things") 
@RequestScoped 
public class ThingsResource{ 

    @POST 
    @Produces({MediaType.APPLICATION_XML, MediaType.APPLICATION_JSON}) 
    public Response create(final Thing thing){ 
     utx.begin(); 
     em.joinTransaction(); 
     final ThingEntity thingEntity = new ThingEntity(thing); 
     em.persist(thing); 
     utx.commit(); 
     final URI uri = uriInfo.getAbsolutePathBuilder() 
      .path(Long.toString(thingEntity.getId())).build(); 
     return Response.created(uri).build(); 
    } 

    @PersistenceContext(unitName = "somePU") 
    private transient EntityManager em; 

    @Resuorce 
    private transient UserTransaction ut; 

    @Context 
    private transient UriInfo uriInfo; 
} 
संबंधित मुद्दे