Spring Boot整合RabbitMQ RelayMessageBroker使用STOMP事务报Bad transaction错误
错误诱因
核心原因是RabbitMQ的STOMP适配器收到的事务ID与客户端发起BEGIN帧时声明的事务ID不匹配。从错误日志里Invalid transaction identifier: "tx-1"可以看到,RabbitMQ拿到的事务ID带有额外的双引号,和实际生成的事务IDtx-1不一致,导致校验失败返回错误,Spring的StompBrokerRelay收到后端Broker的错误帧后,按照STOMP规范主动断开了客户端连接。
常见触发场景包括:
- 使用的STOMP JS客户端(如旧版stompjs、@stomp/stompjs)存在序列化bug,发送SEND帧时自动给transaction头的字符串值加了双引号
- Spring StompBrokerRelay的头转换逻辑存在异常,透传事务头时意外添加了引号
- 客户端BEGIN、SEND、COMMIT三个帧的transaction头值没有严格对齐
排查解决步骤
- 先确认STOMP帧的header是否正常:给STOMP客户端添加debug回调打印所有收发的STOMP帧,同时在send前打印日志
console.log('transaction id:', tx.id),确认三个事务相关帧的transaction值完全一致、无多余符号 - 如果确认是客户端自动生成ID、序列化带引号的问题,可以手动指定事务ID,修改代码如下:
// 手动指定无特殊字符的事务ID,规避客户端自动生成逻辑的bug const txId = 'tx-' + Date.now() var tx = clientRef.client.begin(txId); clientRef.client.send("/queue/onnext", { transaction: txId, durable:false, exclusive:false, "auto-delete":false }, 'test123'); tx.commit() - 检查Spring Boot的StompBrokerRelay配置,确认没有自定义头转换器修改事务头:排查是否实现了
StompHeaderAccessor或者MessageConverter的自定义逻辑,意外给字符串类型的头值加了引号,标准配置参考:@Configuration @EnableWebSocketMessageBroker public class WebSocketConfig implements WebSocketMessageBrokerConfigurer { @Override public void configureMessageBroker(MessageBrokerRegistry config) { config.enableStompBrokerRelay("/queue", "/topic") .setRelayHost("localhost") .setRelayPort(61613) .setClientLogin("guest") .setClientPasscode("guest"); config.setApplicationDestinationPrefixes("/app"); } @Override public void registerStompEndpoints(StompEndpointRegistry registry) { registry.addEndpoint("/ws").withSockJS(); } } - 升级RabbitMQ STOMP插件、Spring Messaging依赖到最新稳定版,修复已知的事务头处理bug
内容的提问来源于stack exchange,提问作者Only X
相关产品推荐
相关产品推荐

