Jakarta ee HornetQ:如何重用XAConnection和XASession
在我的JBoss应用程序中,在多个worker上重用XAConnection和XASession时,我遇到了一些问题。我已经设法将问题简化为一种方法。它应该能够使用相同的连接和会话生成和使用消息。目前,我的应用程序有很多队列和工作进程,每个工作进程当前都在启动和启动自己的连接和会话,而不是共享它。难道这不可能吗 下面是我的代码示例:Jakarta ee HornetQ:如何重用XAConnection和XASession,jakarta-ee,jboss,jms,hornetq,xa,Jakarta Ee,Jboss,Jms,Hornetq,Xa,在我的JBoss应用程序中,在多个worker上重用XAConnection和XASession时,我遇到了一些问题。我已经设法将问题简化为一种方法。它应该能够使用相同的连接和会话生成和使用消息。目前,我的应用程序有很多队列和工作进程,每个工作进程当前都在启动和启动自己的连接和会话,而不是共享它。难道这不可能吗 下面是我的代码示例: import org.apache.log4j.Logger; import javax.annotation.PostConstruct; import java
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);
}
}
}
现在我在会话中遇到一个异常。Commit():
在实际接收消息之前,需要提交会话对象。在producer.send语句之后,需要添加session.commit 此外,我建议在最后关闭制作人 另一件看起来错误的事情是,在生产者被销毁之后创建消费者 我看到了一些(实际上是2个)混淆: i-您正在使用XA会话,但未声明任何事务边界。。。这通常在会话bean和MDB上完成。我不确定你能在这个无国籍的网站上这么做 如果不使用任何声明性事务,则必须手动登记XID ii-jmsXA是默认的资源适配器连接工厂。它上面已经有一个游泳池了。因此,无论何时创建新会话,您都将从池中取出。当您关闭它时,您将其返回池中 您可以使用常规连接工厂。只要在InVMConnectionFactory中(或者您在单机版上定义的任何内容,假定您在JBoss上,则在PooledConnectionFactory之外),然后只使用常规JMS 即使常规连接工厂也可以与XA一起使用,但是在这种情况下,您需要确保直接使用事务管理器的api来登记它 如果您使用常规连接工厂,那么您可以让它保持连接,只要您愿意 请告诉我进展如何,我会帮助你。我知道你开始了一项悬赏……但我会免费回答:) 我在EJB教程中找不到任何关于使用单例事务的示例 我建议您通过无状态或有状态会话Bean使用它,然后将@TransactionAttribute应用于该Bean Java EE 6教程提供了一些很好的信息: 请注意,在您提交之前,消息将不可用。因此,如果您在事务中发送消息,您将无法在同一事务中接收它 在edit1示例中,您正在发送一条消息,并在同一事务中使用它。这是行不通的,因为您首先需要提交生成方法,然后才能使用它。在这种情况下,您需要两个事务,因此Edit1已损坏
另外:确保在最后关闭连接。由于您使用的是JmsXA(或池连接工厂),因此应用程序服务器将自动完成轮询。感谢您的回复。在producer.send之后的行中添加commit会导致一个XA连接:javax.jms.TransactionProgressException。我已经撤销了您的赏金@Dennis。您可以根据需要重新提供并奖励它。这给了两个答案又一次机会。谢谢你的回复。我会试着调查一下。你能给我一个第1部分描述的解决方案的小例子吗?我没有任何例子可以在一个类中使用。您应该在EE6上查找事务注释。非常抱歉,我刚刚把悬赏放在了错误的答案上(有什么方法可以奖励你吗?我已经用EDIT1编辑了主题。我已经将代码转换为bean并添加了@TransactionAttribute。现在我在会话中得到了TransactionProgressException。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:]