JMS/Seam -- 创建会话时出现异常?

5

我有一个JBoss Seam 2.3应用程序,它试图将事件写入JBoss AS 7.1上的JMS队列。写操作发生在无状态EJB中,并使用标准的Seam注入机制。代码类似于以下内容(不是精确的代码片段,只是展示我正在做的事情的类型):

@Name("myEjb")
@Stateless
public class MyEjb {

   ...

   @In
   private QueueSession queueSession;

   @In
   private QueueSender myQueueSender;

   ...


   public foo() {
       ...
       // Code to place a TextMessage on the queue
       ...
   }
}

然而,我注意到当应用程序负载较重,而且这个方法被频繁调用时,日志中会出现以下异常:

21:58:57,800 ERROR [org.hornetq.ra.HornetQRASessionFactoryImpl] (http--0.0.0.0-8080-1) Could not create session: javax.jms.IllegalStateException: Only allowed one session per connection. See the J2EE spec, e.g. J2EE1.4 Section 6.6

at org.hornetq.ra.HornetQRASessionFactoryImpl.allocateConnection(HornetQRASessionFactoryImpl.java:816)

at org.hornetq.ra.HornetQRASessionFactoryImpl.createQueueSession(HornetQRASessionFactoryImpl.java:237)

at org.jboss.seam.jms.QueueSession.create(QueueSession.java:38) [jboss-seam.jar:2.3.0.Final]

at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method) [rt.jar:1.7.0_07]

at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:57) [rt.jar:1.7.0_07]

at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43) [rt.jar:1.7.0_07]

at java.lang.reflect.Method.invoke(Method.java:601) [rt.jar:1.7.0_07]

at org.jboss.seam.util.Reflections.invoke(Reflections.java:22) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.util.Reflections.invokeAndWrap(Reflections.java:144) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.Component.callComponentMethod(Component.java:2313) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.Component.callCreateMethod(Component.java:2236) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.Component.newInstance(Component.java:2196) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.Component.getInstance(Component.java:2034) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.Component.getInstance(Component.java:1996) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.Namespace.getComponentInstance(Namespace.java:60) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.Component.getInstanceInAllNamespaces(Component.java:2427) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.Component.getValueToInject(Component.java:2366) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.Component.injectAttributes(Component.java:1743) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.Component.inject(Component.java:1561) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.core.BijectionInterceptor.aroundInvoke(BijectionInterceptor.java:61) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.intercept.SeamInvocationContext.proceed(SeamInvocationContext.java:68) [jboss-seam.jar:2.3.0.Final]

at org.jboss.seam.core.MethodContextInterceptor.aroundInvoke(MethodContextInterceptor.java:44) [jboss-seam.jar:2.3.0.Final]

foo()方法在请求发送到RESTful服务后最终被调用。客户端可能会连续调用此服务多次,但它们都是不同的调用。

有什么想法会导致这种异常吗?我以前成功地使用过Seam和JMS,没有任何问题,但是这个应用程序对JMS队列进行的写入比我以前编写的那些要多得多。我的components.xml文件设置正确,我在那里没有收到任何错误。另外,只要我单独调用foo()并向队列写入消息,就没有问题。只有当我对foo()方法进行大量的连续调用时才会出现此问题。

有什么想法吗?有什么建议可以尝试或排除故障的方法吗?

更新:我应该提到我正在使用的消息队列是HornetQ嵌入在JBoss AS 7.1中。我认为这似乎是关于多个线程尝试写入消息到队列的某种问题。我没有其他信息,也不知道如何解决这个问题。我非常感谢您能给予任何帮助。

1个回答

3

这是JCA规范的一部分。当您使用一个池化连接工厂时,由于JCA连接在内部是连接/会话的元组,因此不能创建多个会话。

JCA连接将为您提供池和与XA的无缝集成。如果您不需要XA,可以只使用在standalone.xml中定义的常规连接工厂。

如果您确实需要池和XA,则为每个会话创建一个连接,这样您就可以解决此问题了。


那么,为了完成这个,我需要做什么改变呢?这是JBoss配置中需要更改的内容吗?我的Seam components.xml文件呢? - Shadowman
首先,您需要确保没有泄漏连接。关闭您的连接和会话...我没有太多材料可以查看...我需要从您的应用程序中看到更多内容。我无法回答有关接缝配置的问题,但如果您提供一个可运行的示例,我可以看一下。 - Clebert Suconic
可能是Seam上的一个bug...如果您提供更多的代码样本,我就可以找出问题所在...如果您愿意,您可以在hornetq的论坛上添加一个运行样本,然后我可以回到这里给您最终的答案。 - Clebert Suconic
还有,只是为了让我更了解这个问题,什么情况下我会选择XA而不是非XA?是否有需要优先考虑其中一个的用例? - Shadowman
这更多是关于池化与非池化的问题。当使用池化连接工厂时,您将获得与XA的集成。这意味着如果您接收到一条消息并在数据库上插入记录,则事务管理器将保证两个分支都要么提交,要么回滚,以便您不会从无中创建数据。 - Clebert Suconic

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接