Spring boot 使用事务会话时,使用Artemis和Spring JMS的消息分组不起作用
消息分组似乎不起作用Spring boot 使用事务会话时,使用Artemis和Spring JMS的消息分组不起作用,spring-boot,jms,spring-jms,activemq-artemis,Spring Boot,Jms,Spring Jms,Activemq Artemis,消息分组似乎不起作用 在将字符串属性JMSXGroupID设置为'product=paper'之后,我的生产者应用程序通过JMS将消息发送到队列 我的producer应用程序发送另一条消息的方式与'product=paper'相同 在Artemis UI中浏览消息头时,我可以看到队列中的两条消息\u AMQ\u GROUP\u ID在这两个字段中的值均为'product=paper'JMSXGroupID不存在 当我调试使用SpringJMS的侦听器应用程序时,并发度为15-15(15 min
JMSXGroupID
设置为'product=paper'
之后,我的生产者应用程序通过JMS将消息发送到队列'product=paper'
相同\u AMQ\u GROUP\u ID
在这两个字段中的值均为'product=paper'
<代码>JMSXGroupID不存在\u AMQ\u GROUP\u ID
不存在,JMSXGroupID
的值为null,而不是'product=paper'
\u AMQ\u GROUP\u ID
翻译回JMSXGroupID
有关?或者SpringJMS没有将其多个使用者线程注册为不同的使用者,以便代理看到多个使用者
编辑:
通过注释掉与使用容器工厂bean方法中的事务会话有关的行,我能够使消息分组在我的应用程序中工作。这似乎与使用事务性会话有关
编辑2:
下面是一个针对本地独立Artemis代理(版本2.10.1)并使用Spring Boot 2.2.0运行的自包含应用程序:
GroupID应用程序(spring启动应用程序和bean):
pom.xml:
<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<parent>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-parent</artifactId>
<version>2.2.0.RELEASE</version>
<relativePath/> <!-- lookup parent from repository -->
</parent>
<groupId>com.reproduce</groupId>
<artifactId>groupid</artifactId>
<version>0.0.1-SNAPSHOT</version>
<name>groupid</name>
<description>Demo project for Spring Boot</description>
<properties>
<java.version>1.8</java.version>
</properties>
<dependencies>
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-artemis</artifactId>
</dependency>
<dependency>
<groupId>com.fasterxml.jackson.datatype</groupId>
<artifactId>jackson-datatype-jsr310</artifactId>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-maven-plugin</artifactId>
</plugin>
</plugins>
</build>
</project>
4.0.0
org.springframework.boot
spring启动程序父级
2.2.0.1发布
复制
用户组
0.0.1-快照
用户组
SpringBoot的演示项目
1.8
org.springframework.boot
弹簧靴起动器artemis
com.fasterxml.jackson.datatype
jackson-datatype-jsr310
org.springframework.boot
springbootmaven插件
您可以看到,尽管所有这些消息都具有相同的组id,但它们被不同的侦听器容器线程记录。如果您从bean定义中注释掉事务管理器,它将重新开始工作。这都是关于消费者缓存的。默认情况下,当使用外部TXM时,将禁用缓存,以便在新的使用者上接收每条消息 对于这个应用程序,你真的不需要事务管理器,
sessiontransactited
就足够了-容器将使用本地事务
如果出于某种原因必须使用外部事务管理器,请考虑更改缓存级别。
factory.setCacheLevel(DefaultMessageListenerContainer.CACHE_CONSUMER);
请参阅DMLC javadocs
/**
* Specify the level of caching that this listener container is allowed to apply.
* <p>Default is {@link #CACHE_NONE} if an external transaction manager has been specified
* (to reobtain all resources freshly within the scope of the external transaction),
* and {@link #CACHE_CONSUMER} otherwise (operating with local JMS resources).
* <p>Some Java EE servers only register their JMS resources with an ongoing XA
* transaction in case of a freshly obtained JMS {@code Connection} and {@code Session},
* which is why this listener container by default does not cache any of those.
* However, depending on the rules of your server with respect to the caching
* of transactional resources, consider switching this setting to at least
* {@link #CACHE_CONNECTION} or {@link #CACHE_SESSION} even in conjunction with an
* external transaction manager.
* @see #CACHE_NONE
* @see #CACHE_CONNECTION
* @see #CACHE_SESSION
* @see #CACHE_CONSUMER
* @see #setCacheLevelName
* @see #setTransactionManager
*/
public void setCacheLevel(int cacheLevel) {
/**
*指定允许此侦听器容器应用的缓存级别。
*如果已指定外部事务管理器,则默认值为{@link#CACHE_NONE}
*(重新获得外部交易范围内的所有资源),
*和{@link#CACHE_CONSUMER}否则(使用本地JMS资源操作)。
*一些JavaEE服务器只向正在进行的XA注册其JMS资源
*在新获得的JMS{@code Connection}和{@code Session}情况下的事务,
*这就是为什么这个侦听器容器在默认情况下不缓存任何这些内容。
*但是,这取决于服务器关于缓存的规则
*事务性资源,考虑将此设置切换为至少
*{@link#CACHE_CONNECTION}或{@link#CACHE_SESSION}甚至与
*外部事务管理器。
*@see#CACHE#u NONE
*@see#CACHE_连接
*@see#CACHE_SESSION
*@see#CACHE#u消费者
*@see#setCacheLevelName
*@see#setTransactionManager
*/
public void setCacheLevel(int cacheLevel){
如果从用例中删除Spring JMS,只使用普通JMSMessageConsumer
,会发生什么?删除Spring JMS将表明问题是与Spring JMS有关还是与Artemis本身有关。请参阅。这是Artemis客户端中的一个bug(2.6.4);它适用于2.10.1。@GaryRussell我认为这是一个单独的问题。在同一个问题的示例中,您链接的组id实际起作用,只是标题中没有显示出来。您可以使用main()编写一个简单的Java应用程序
method,订阅主题并多次运行该应用程序。幸好您添加了此注释;由于某些原因,我没有收到昨天的注释通知,并且这些注释不在我的回复历史记录中。我将查看并返回给您。完成了!谢谢。是否有好的文档帮助我理解tran您会推荐使用spring jms进行操作管理和缓存吗?这些配置对我来说仍然很神奇。我不知道除了javadocs和spring框架参考jms和事务章节之外还有什么。通常,如果您想要同步事务(例如DB和jms),您只需要插入事务管理器或者,如果您在托管容器(JEE)中运行,后者就是他们决定使用这些默认值的原因(当SpringJMS第一次创建时,JEE是常用的)。
factory.setCacheLevel(DefaultMessageListenerContainer.CACHE_CONSUMER);
/**
* Specify the level of caching that this listener container is allowed to apply.
* <p>Default is {@link #CACHE_NONE} if an external transaction manager has been specified
* (to reobtain all resources freshly within the scope of the external transaction),
* and {@link #CACHE_CONSUMER} otherwise (operating with local JMS resources).
* <p>Some Java EE servers only register their JMS resources with an ongoing XA
* transaction in case of a freshly obtained JMS {@code Connection} and {@code Session},
* which is why this listener container by default does not cache any of those.
* However, depending on the rules of your server with respect to the caching
* of transactional resources, consider switching this setting to at least
* {@link #CACHE_CONNECTION} or {@link #CACHE_SESSION} even in conjunction with an
* external transaction manager.
* @see #CACHE_NONE
* @see #CACHE_CONNECTION
* @see #CACHE_SESSION
* @see #CACHE_CONSUMER
* @see #setCacheLevelName
* @see #setTransactionManager
*/
public void setCacheLevel(int cacheLevel) {