我的Java EE 6 Web应用程序已达到可在单个事务中发送的最大JMS消息数,我需要在多个事务中执行此操作。当事务由容器管理时,这样做的最佳方法是什么?是否可以在不同的事务中使用相同的MessageProducer(使用注释为@TransactionAttribute(TransactionAttributeType.REQUIRES_NEW)
的EJB方法)
我正在使用Glassfish v3和OpenMQ。
此问题Maximum number of messages sent to a Queue in OpenMQ?中涵盖了OpenMQ中最大消息数的问题。
答案 0 :(得分:1)
如果您无法在应用程序服务器中找到使用容器管理事务完成此操作的方法,并且您不想使用编程事务,则可以考虑使用Aggregator和/或Splitter企业集成模式。
在您的制作人中,将您的个人消息或对象聚合成一条复合消息。在消费者端,拆分复合消息以进行适当的处理。
答案 1 :(得分:0)
@theo:太棒了。所以基本上你目前的业务流程是: -
前端(JSF UI)操作 - > EJB 图层(交易开始)--->发布 消息到FINAL QUEUE。
现在这是解决问题的一种方法: - 您可以在两者之间定义拆分队列: - 所以流程可能是
: - 前端(JSF UI)操作 - > EJB层 - > SPLIT QUEUE ---> MDB - > FINAL 队列
要么, 前端(JSF UI) 操作 - > SPLIT QUEUE ---> EJB layer - > FINAL QUEUE
所以基本的想法是,因为每个交易限制你有n个消息,如果你没有消息要发布m> n和m> 0;那么你可以通过在中途引入SPLIT QUEUE将m分成块。我在我的一个项目中完成了这个。如果您有任何问题,请告诉我。
虽然我不完全了解您的数据模型/业务流程,但这里是概要。 让我假设你的JMS消息的有效载荷数据来自一组表,这些表可以由标识符Un唯一地标识。因此,您要发布由U1,U2 ... U1000标识的1000条JMS消息。 所以基本上你可以定义一个内部SPLIT队列。在您的Java代码中,将1000个标识符拆分为每个块200个:所以{U1 ... U200},{U201 .... U400),{U401 ... U600),(U601,... U800)和(U801) ...... U1000)。您可以将这些标识符列表作为Java.util.List有效内容发布到Split Queue上。 您可以使用事务属性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
}
希望这澄清。