我最近不得不支持一位同事验证为什么有些系统测试没有通过wildfly,系统测试一直在weblogic和玻璃鱼上传递。
在分析了日志之后,很明显原因与备份线程过早提交到队列的JMS消息有关,当期望是当MDB的入口点容器管理事务提交时将提交消息。因此,消息在发送它的MDB运行之前就会消失。
在weblogic中,为了实现预期的行为,您需要确保在获取容器(由XA配置)给出的连接工厂时,使用transacted = true和acknowate = session transacted设置connection.createseesion。
在类似于此URL中描述的过程中,http://www.mastertheboss.com/jboss-server/jboss-jms/sending-jms-messages-over-xa-with-wildfly-jboss-as除了在上面的代码片段中设置了自动确认,并且第一个参数设置为false。
在使用我们的weblogic和glass fish配置时,没有提交任何内容,系统的行为就好像要回滚的JMS消息一样。
如果要使用上面示例中的配置,则会发生的情况是JMS消息立即发生,并且消费者MDB在生产者事务实际结束之前立即启动被触发,导致系统测试失败。
根据官方JMS配置,通过使用具有transaction = XA属性的connection-pooled工厂,容器应立即将事务的提交绑定到父事务的生命周期。
有关Java:/ JmsXa连接工厂,请参阅下面的官方文档。
https://docs.jboss.org/author/display/WFLY10/Messaging+configuration
我的同事最初使用非池化连接工厂,但从那时起注射信息参考已被修复。我已经在棚文件中尝试了所有可能的参数组合,但我的结果是sitll:要么发送太快要么是从未发送过。
总结所有其他资源都是XA。即oracle db正在使用XA驱动程序。
任何人都可以确认是否只在父事务提交正在工作时发送JMS消息,如果是,那么如何配置会话?
我将检查我的同事是否在Men's使用的连接工厂的配置方面没有犯错,以消耗队列中的消息。但是如果那个也是XA ......那么这是一个大问题。
所以问题是固定的。
在事务结束时将JMS消息提交到队列非常有效。
这个问题有两个方面:(a)我正在寻找的第一个代码地址问题是不正确的。有人决定将他自己的发送电报写入其他地方的队列API,并且没有使用中央API来进行电报,因此对注入连接工厂的任何修改实际上都没有生效。过时的连接工厂仍在使用中。
(b)一旦找到正确的API,就可以通过使用上面帖子中提到的widlfy XA池连接工厂来轻松实现该机制。调整的一件事是connection.CreationSession api。
JEE 7中的API已经扩大,现在比jEE 6更好地记录。要在容器中发送JMS消息作为XA事务的一部分,应该执行:connection.createSession(),不带任何参数。
这可以在连接javadoc中轻松看到:
https://docs.oracle.com/javaee/7/api/javax/jms/Connection.html
报价1:
此方法已被createSession(int sessionMode)方法取代,该方法使用单个参数指定相同的信息,并通过用于Java EE JTA事务的createSession()方法取代。应用程序应考虑使用这些方法而不是此方法。
第2条:
在Java EE Web或EJB容器中,当存在正在进行的活动JTA事务时:
事务处理和确认模式都被忽略。会话将参与JTA事务,并在提交或回滚该事务时提交或回滚,而不是通过调用会话的提交或回滚方法。由于两个参数都被忽略,因此建议开发人员使用不带参数的createSession(),而不是此方法。
不合适。应该做的是创建没有任何参数的会话,并让容器处理其余的参数。它做得很好。