2013-09-05 10 views
5

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

यहाँ मेरी कोड उदाहरण है:

import org.apache.log4j.Logger; 
import javax.annotation.PostConstruct; 
import javax.annotation.PreDestroy; 
import javax.ejb.Singleton; 
import javax.ejb.Startup; 
import javax.jms.*; 
import javax.jms.Queue; 
import javax.naming.InitialContext; 

@Singleton 
@Startup 
public class QueueTest { 

    private Logger logger = Logger.getLogger(QueueTest.class); 

    @PostConstruct 
    public void startup() { 
     try { 
      String queue = "queue/Queue1"; 
      String message = "test"; 

      //setting up connection 
      InitialContext iniCtx = new InitialContext(); 
      XAConnectionFactory qcf = (XAConnectionFactory) iniCtx.lookup("java:/JmsXA"); 
      XAConnection connection = qcf.createXAConnection(); 
      connection.start(); 
      logger.debug("creating connection at " + new java.util.Date()); 

      //setting up session 
      XASession session = connection.createXASession(); 
      logger.debug("creating session at " + new java.util.Date()); 

      //find the queue 
      Object queueObj = iniCtx.lookup(queue); 
      Queue jmsQueue = (javax.jms.Queue)queueObj; 

      //adding message to queue 
      javax.jms.MessageProducer producer = session.createProducer(jmsQueue); 
      javax.jms.TextMessage textMessage = session.createTextMessage(message); 
      producer.send(textMessage); 
      producer.close(); 
      logger.debug("Message added to queue"); 

      //receiving message from queue 
      javax.jms.MessageConsumer consumer = session.createConsumer(jmsQueue); 
      javax.jms.TextMessage messageReceived = (javax.jms.TextMessage)consumer.receive(5000); 

      if (messageReceived==null) 
       throw new Exception("No message reveived"); 

      logger.debug("Got message:"+messageReceived.getText()); 
      consumer.close(); 
     } 
     catch(Exception e) { 
      logger.debug("Error: " + e.getMessage(), e); 
     } 
    } 

    @PreDestroy 
    public void shutdown() { 

    } 
} 

यह इस उत्पादन में परिणाम है:

11:47:17,905 DEBUG [QueueTest] (MSC service thread 1-8) creating connection at Thu Sep 05 11:47:17 CEST 2013 
11:47:18,041 DEBUG [QueueTest] (MSC service thread 1-8) creating session at Thu Sep 05 11:47:18 CEST 2013 
11:47:18,065 DEBUG [QueueTest] (MSC service thread 1-8) Message added to queue 
11:47:23,081 DEBUG [QueueTest] (MSC service thread 1-8) Error: No message reveived 

आप देख सकते हैं, कोई संदेश उपभोक्ता द्वारा प्राप्त होता है। क्यूं कर?

संपादित करें 1:

package dk.energimidt.uapi.zigbee.services; 

import org.apache.log4j.Logger; 

import javax.ejb.Stateless; 
import javax.ejb.TransactionAttribute; 
import javax.ejb.TransactionAttributeType; 
import javax.jms.Queue; 
import javax.jms.XAConnection; 
import javax.jms.XAConnectionFactory; 
import javax.jms.XASession; 
import javax.naming.InitialContext; 

@TransactionAttribute(TransactionAttributeType.REQUIRED) 
@Stateless 
public class QueueTestWorkerBean implements QueueTestWorker { 

    private Logger logger = Logger.getLogger(QueueTestWorkerBean.class); 

    public void run() { 
     try { 
      String queue = "queue/Queue1"; 
      String message = "test"; 

      //setting up connection 
      InitialContext iniCtx = new InitialContext(); 
      XAConnectionFactory qcf = (XAConnectionFactory) iniCtx.lookup("java:/JmsXA"); 
      XAConnection connection = qcf.createXAConnection(); 
      connection.start(); 
      logger.debug("creating connection at " + new java.util.Date()); 

      //setting up session 
      XASession session = connection.createXASession(); 
      logger.debug("creating session at " + new java.util.Date()); 

      //find the queue 
      Object queueObj = iniCtx.lookup(queue); 
      Queue jmsQueue = (javax.jms.Queue)queueObj; 

      //adding message to queue 
      javax.jms.MessageProducer producer = session.createProducer(jmsQueue); 
      javax.jms.TextMessage textMessage = session.createTextMessage(message); 
      producer.send(textMessage); 
      producer.close(); 
      session.commit(); 
      logger.debug("Message added to queue"); 

      //receiving message from queue 
      javax.jms.MessageConsumer consumer = session.createConsumer(jmsQueue); 
      javax.jms.TextMessage messageReceived = (javax.jms.TextMessage)consumer.receive(5000); 

      if (messageReceived==null) 
       throw new Exception("No message reveived"); 

      logger.debug("Got message:"+messageReceived.getText()); 
      consumer.close(); 

      connection.close(); 
     } 
     catch(Exception e) { 
      logger.debug("Error: " + e.getMessage(), e); 
     } 
    } 
} 

अब मैं Session.Commit (पर एक अपवाद मिल):

10:46:03,697 DEBUG [QueueTestWorkerBean] (MSC service thread 1-14) creating connection at Tue Sep 17 10:46:03 CEST 2013 
10:46:04,343 DEBUG [QueueTestWorkerBean] (MSC service thread 1-14) creating session at Tue Sep 17 10:46:04 CEST 2013 
10:46:04,355 DEBUG [QueueTestWorkerBean] (MSC service thread 1-14) Error: XA connection: javax.jms.TransactionInProgressException: XA connection 
    at org.hornetq.ra.HornetQRASession.commit(HornetQRASession.java:386) 
    at QueueTestWorkerBean.run(QueueTestWorkerBean.java:45) [library-1.0.0.jar:] 

उत्तर

2

मैं कुछ (वास्तव में 2) मिश्रण वहाँ अप देखने। मुझे यकीन नहीं है कि आप इस स्टेटलेस पर ऐसा कर सकते हैं।

यदि आप किसी भी घोषणात्मक लेनदेन का उपयोग नहीं करते हैं, तो आपको XID मैन्युअल रूप से सूचीबद्ध करना होगा।

ii - jmsXA डिफ़ॉल्ट संसाधन एडाप्टर कनेक्शन फ़ैक्टरी है। इसमें पहले से ही एक पूल है। तो जब भी आप एक नया सत्र बनाते हैं तो आप पूल से बाहर निकल रहे हैं। जब आप इसे बंद करते हैं तो आप इसे पूल में वापस कर रहे हैं।

आप नियमित कनेक्शन फैक्ट्री का उपयोग कर सकते हैं। केवल इनवीएमसीनेक्शन फैक्ट्री (या जो भी आपने अपने स्टैंडअलोन पर परिभाषित किया है, पूलडोनकनेक्शन कारखानों के बाहर जो आप मानते हैं कि आप जेबॉस पर हैं ... और फिर नियमित जेएमएस का उपयोग करें।

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

,।

कृपया मुझे पता है यह कैसे जाता है और मैं आपकी मदद करूंगा। मुझे पता है कि आपने एक बक्षीस शुरू किया है ..लेकिन मैंने इसे मुफ्त में उत्तर दिया होगा :)

मुझे सिंगलटन के साथ लेनदेन का उपयोग करने के बारे में ईजेबी ट्यूटोरियल पर कोई उदाहरण नहीं मिला।

मैं आपको एक स्टेटलेस या स्टेटफुल सत्र बीन के माध्यम से इसका उपयोग करने की सलाह दूंगा और फिर बीन को @ ट्रान्सएक्शन एट्रिब्यूट लागू करूँगा।

http://docs.oracle.com/javaee/6/tutorial/doc/bncij.html

सूचना है कि संदेश उपलब्ध जब तक आप प्रतिबद्ध नहीं होगा:

जावा ईई 6 ट्यूटोरियल इसके बारे में कुछ अच्छी जानकारी है। तो यदि आप एक लेनदेन के भीतर एक संदेश भेजते हैं तो आप इसे उसी लेनदेन पर प्राप्त नहीं कर पाएंगे।

आपके संपादन 1 उदाहरण पर आप एक संदेश भेज रहे हैं और उसी लेनदेन पर इसका उपभोग कर रहे हैं। यह काम नहीं करेगा क्योंकि आपको इसे उपभोग करने से पहले उत्पादन विधि को पहले करने की आवश्यकता है। आपको इस मामले पर दो लेनदेन की आवश्यकता होगी, इसलिए संपादन 1 टूटा हुआ है।

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

+0

आपके उत्तर के लिए धन्यवाद। मैं इसे देखने की कोशिश करूंगा। क्या आप मुझे भाग 1 में वर्णित समाधान का एक छोटा सा उदाहरण दे सकते हैं? – dhrm

+0

मेरे पास एकल कक्षा में उपयोग के लिए कोई उदाहरण नहीं है। आपको ईई 6 –

+0

पर लेनदेन एनोटेशन की तलाश करनी चाहिए। मैंने पोस्ट को अधिक जानकारी के साथ संपादित किया है –

1

आप वास्तव में प्राप्त कर सकते हैं इससे पहले कि आप प्रतिबद्ध करने के लिए की जरूरत है सत्र वस्तु। Producer.send कथन के बाद, आपको session.commit जोड़ने की आवश्यकता है।

इसके अतिरिक्त मैं निर्माता को अंत में बंद करने की अनुशंसा करता हूं।

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

मैं - आप एक XA सत्र का उपयोग कर रहे हैं, लेकिन आप किसी भी लेनदेन सीमाओं की घोषणा नहीं कर रहे हैं ... जो आम तौर पर सत्र बीन्स और एमडीबी पर किया जाता है:

+0

आपके उत्तर के लिए धन्यवाद। Producer.send के बाद लाइन में प्रतिबद्धता जोड़ना, एक * एक्सए कनेक्शन में परिणाम: javax.jms.TransactionInProgressException *। – dhrm

+0

बकाया गलत जवाब पर रखा गया था। मुझे माफ कर दो। – dhrm

+0

मैंने आपके बक्षीस को रद्द कर दिया है, @ डेनिस। आप इसे फिर से पेश कर सकते हैं और इसे वांछित के रूप में पुरस्कृत कर सकते हैं। यह * दोनों * पर एक और शॉट का जवाब देता है। – Shog9

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