0

我的 Java EE 6 Web 应用程序已达到可以在单个事务中发送的最大 JMS 消息数,我需要在多个事务中执行此操作。当事务由容器管理时,最好的方法是什么?在不同的事务中使用相同的 MessageProducer 是否可以(使用带有注释的 EJB 方法@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)

我正在使用 Glassfish v3 和 OpenMQ。

此 SO 问题中涵盖了 OpenMQ 中的最大消息 数的问题Maximum number of messages sent to a Queue in OpenMQ? .

4

2 回答 2

1

如果您无法找到在应用程序服务器中使用容器管理事务来完成此任务的方法,并且您不想使用编程事务,则可以考虑使用聚合器和/或拆分器企业集成模式。

在您的生产者中,将您的单个消息或对象聚合为一条复合消息。在消费者端,拆分复合消息以进行适当的处​​理。

于 2011-06-04T16:36:19.060 回答
0

@theo:太好了。所以基本上你目前的业务流程是:-

前端(JSF UI)操作--> EJB 层(事务开始)---> 将消息发布到最终队列。

现在这是解决您的问题的一种方法:-您可以在两者之间定义一个拆分队列:-因此流可能是

要么:- 前端(JSF UI)操作-->EJB 层-->SPLIT QUEUE--->MDB-->FINAL QUEUE
或者,前端(JSF UI)操作-->SPLIT QUEUE---> EJB 层-->FINAL QUEUE

所以基本的想法是因为每个事务限制有 n 个消息传递者,如果你有 m 个要发布的消息,其中 m>n 和 m>0;然后你可以通过在中间引入一个 SPLIT QUEUE 将 m 分成 m\n 次块。我已经在我的一个项目中做到了这一点。如果您有任何问题,请告诉我。


@Theo:我不太清楚 Asynkronos 提到了什么。但我的意思是:-您的 JSF UI 操作导致(让我们说)1000 条 JMS 消息到您的 FINAL 队列。现在让我们假设,每个事务限制有 200 条 JMS 消息。你可以做的可能是: -

虽然我不完全了解您的数据模型/业务流程,但这里是概要。让我假设您的 JMS 消息的有效负载数据来自一组可以由标识符 Un 唯一标识的表。因此,您有 1000 条要发布的 JMS 消息,由 U1、U2....U1000 标识。所以基本上你可以定义一个内部 SPLIT 队列。在您的 Java 代码中,将 1000 个标识符拆分为每个 200 个块:{U1...U200},{U201...U400),{U401...U600),(U601,..U800) 和 (U801 ,...U1000)。您可以将这些标识符列表作为 Java.util.List 有效负载发布到您的拆分队列中。您可以使用事务属性 REQUIRES-NEW 定义 MDB 侦听 SPLIT 队列。在 MDB 代码中,您可以获取标识符列表并执行 for 循环:

onMessage(Message m){
ObjectMessage objectMsg=(ObjectMessage) m;
java.util.List list=(List) objectMsg.getObject();
//open  a JMS session
for (String identifer : list){

//fetch data from DB for particular identifier.

//prepare output JMS payload for that particular identifier.

//publish JMS data onto FINAL queue
}

希望这可以澄清。

于 2011-06-05T07:54:03.120 回答