【问题标题】:How to send multiple JMS messages in blocks (each in a new transaction)如何在块中发送多个 JMS 消息(每个都在一个新事务中)
【发布时间】:2011-09-08 04:44:23
【问题描述】:

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

我正在使用 Glassfish v3 和 OpenMQ。

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

【问题讨论】:

  • 你能解释一下你的业务用例流程吗?建筑层......也许我可以帮助你......
  • @ag112 这是一个三层的 Java EE 6 Web 应用程序,具有数据库层(ORM 使用 JPA 2.0)、业务逻辑层中的 EJB 和前端的 JSF 2.0。我使用 JMS 异步发送传入消息的通知。在某些情况下,一条消息可能会导致数千条通知(JMS 消息),因此每个事务最多可达到 1000 条 JMS 消息。

标签: jakarta-ee jms glassfish-3 openmq


【解决方案1】:

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

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

【讨论】:

  • 这个想法+1。我需要考虑它是否适用于我的情况,因为我需要确保消费者端的处理与仅发送 JMS 消息时相同(因为我正在使用 JMS 消息重新传递以防万一失败,我需要确保每条 JMS 消息的处理都是独立处理的)。
【解决方案2】:

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

前端(JSF UI)操作--> EJB 层(交易开始)--->发布 消息到 FINAL QUEUE。

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

要么:--前端(JSF UI)操作-->EJB层-->SPLIT QUEUE--->MDB-->FINAL 排队
要么, 前端(JSF UI) 操作-->SPLIT QUEUE-->EJB 层-->最终队列

所以基本的想法是因为每个事务限制有 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
}

希望这可以澄清。

【讨论】:

  • 您说的是 Asynkronos 在他的回答中提出的聚合器/拆分器模式吗?或者您所说的 SPLIT QUEUE 到底是什么意思?
猜你喜欢
  • 2018-09-07
  • 2014-11-05
  • 2012-04-05
  • 2019-10-23
  • 2021-07-06
  • 2018-07-18
  • 1970-01-01
  • 2019-01-28
  • 1970-01-01
相关资源
最近更新 更多