如何以块的形式发送多个 JMS 消息(每个消息都在一个新事务中)
我的 Java EE 6 Web 应用程序已达到可在单个事务中发送的 JMS 消息的最大数量,并且我需要在多个事务中执行此操作。当事务由容器管理时,最好的方法是什么?是否可以在不同事务中使用相同的 MessageProducer(使用用 @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
注释的 EJB 方法)
我正在使用 Glassfish v3 和 OpenMQ。
OpenMQ中最大消息数量的问题在这个SO问题中有所涉及 发送到 OpenMQ 队列的最大消息数?。
My Java EE 6 Web application has reached the maximum number of JMS messages that can be sent in a single transaction and I need to do it in several transactions. What would be the best way of doing this when transactions are managed by the container? Is it OK to use the same MessageProducer across different transactions (using an EJB method annotated with @TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
)
I'm using Glassfish v3 and OpenMQ.
The problem with the maximum number of messages in OpenMQ is covered in this SO question Maximum number of messages sent to a Queue in OpenMQ?.
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
如果您无法找到一种方法来通过应用程序服务器中的容器管理事务来完成此任务,并且您不想使用编程事务,则可以考虑使用聚合器和/或拆分器企业集成模式。
在生产者中,将各个消息或对象聚合成一个复合消息。在消费者端,拆分复合消息以进行适当的处理。
If you're unable to find a way to accomplish this with container-managed transactions in your application server, and you don't want to use programmatic transactions, you can consider using the Aggregator and/or Splitter enterprise integration patterns.
In your producer, aggregate your individual messages or objects into one composite message. On the consumer end, split out the composite message for appropriate processing.
@theo:太棒了。所以基本上你当前的业务流程是:-
现在这是解决您的问题的一种方法:-
您可以在两者之间定义一个分割队列:-
所以流量可以是
所以基本的想法是,因为每个事务限制有 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 循环:
希望这一点能够澄清。
@theo: great. So basically your current business flow is:-
Now here is one way of solving ur problem:-
you can define a split queue in between:-
So flow could be
So basic idea is since you have n number of messagers per transaction limit and if you have m no of messages to be published where m>n and m>0; then you can split m into blocks m\n times by introducing a SPLIT QUEUE in mid way. I had done this in my one of projects. Let me know if you have any questions.
@Theo: I am not very clear what Asynkronos mentioned. But here is what I meant:-
You JSF UI operation results into (let us say) 1000 JMS messages to your FINAL queue.
Now let us suppose, there is 200 JMS messages per transaction limit.
What you can do possibly is:-
Though I don't know ur data model/business flow completely, but here is synopsis.
Let me assume ur JMS message's payload data is coming from a set of tables which can be uniquely identified by identifier Un. So you have 1000 JMS messages to be published identified by U1,U2....U1000.
So basically You can define an internal SPLIT queue. In your Java code, split 1000 identifiers into block of 200 each: so {U1...U200},{U201....U400),{U401...U600),(U601,..U800) and (U801,...U1000). You can publish these list of identifiers onto your Split Queue as Java.util.List payload.
You can define MDB listening SPLIT queue with transaction attribute REQUIRES-NEW.
In MDB code, you can get list of identifiers and do a for loop:
Hope this clarifies.