我在带有MDB的分布式事务环境中使用HornetQ
。我从JMS文档中读到,我们不应经常创建Connection实例,而是应该重用连接并在需要时创建JMS会话。所以我写了一个代码,它创建了JMS连接,然后重用它。但是在重用JMS连接对象时遇到了以下异常。
无法创建会话:每个连接只允许一个会话。 请参阅J2EE规范,例如J2EE1.4第6.6节
我在这方面阅读了很少的博客,但它们都是针对seam框架的。
这是我的代码
public class DefaultService implements IMessageService {
private static final long serialVersionUID = 1L;
private static final Logger logger = LogManager.getLogger(DefaultService.class);
private static final String connectionFactoryJndiName = "java:/JmsXA";
private static volatile Connection connection = null;
private Session session = null;
@Override
public void sendMessage(String destinationStr, Serializable object) {
try {
Destination destination = jmsServiceLocator.getDestination(destinationStr);
ObjectMessage message = session.createObjectMessage();
message.setObject(object);
MessageProducer messageProducer = session.createProducer(destination);
messageProducer.send(destination, message);
messageProducer.close();
logger.trace("Sent JMS Messagae for: " + object.getClass().getName());
}
catch (NamingException e) {
throw new RuntimeException("Couldn't send jms message", e);
}
catch (JMSException e) {
throw new RuntimeException("Couldn't send jms message", e);
}
}
@Override
public void close() {
try {
if (session != null) {
session.close();
}
}
catch (Exception e) {
logger.error("Couldn't close session", e);
}
}
}
我正在使用JBoss EAP 6
。
我在这里错过了任何设置吗?
答案 0 :(得分:2)
在JCA连接(即您使用PooledConnectionFactory的连接)上,您应该只为每个连接创建一个Session。这是EE规范的一部分。 (一直以来)。
这是因为这些连接是合并的,如果每个连接使用多个会话,则无法将它们放回池中。
如果您切换非池化连接工厂(用于远程客户端的工厂),您可以按照自己的方式工作,但是您会错过应用程序服务器的池化。 EE组件通常是短暂的,打开/关闭JMS连接(任何连接都更精确),这是一项昂贵的操作。