Azure Service Bus订阅RECEIVE AND DELETE模式下JMS 1.0编程确认报错求助
问题分析与解决方案
核心矛盾:RECEIVE AND DELETE模式无需手动确认
Azure Service Bus的RECEIVE AND DELETE模式下,消息被客户端接收后会立即从订阅中删除,不需要调用acknowledge()方法手动确认。你当前代码中使用Session.CLIENT_ACKNOWLEDGE会话模式,和订阅的接收模式冲突,这是引发异常的关键原因之一。
代码修复步骤
1. 修正连接工厂初始化
原代码中ServiceBusJmsConnectionFactory的构造参数错误,第二个参数应该是ServiceBusJmsConnectionFactorySettings而非重复创建工厂实例:
ServiceBusJmsConnectionFactorySettings settings = new ServiceBusJmsConnectionFactorySettings(); // 可根据需求配置设置,比如会话模式、重试策略等 ConnectionFactory factory = new ServiceBusJmsConnectionFactory(<CONNECTION_STRING>, settings);
2. 匹配会话模式与订阅接收模式
因为订阅是RECEIVE AND DELETE模式,会话应该使用Session.AUTO_ACKNOWLEDGE(自动确认,和模式匹配),或者直接使用非事务性会话:
// 非事务性会话 + 自动确认,符合RECEIVE AND DELETE模式 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE);
如果坚持使用事务性会话,需要确保订阅模式为PEEK LOCK,且手动提交事务,但这和你当前的RECEIVE AND DELETE模式不兼容。
3. 修正变量引用错误
原代码中session.CLIENT_ACKNOWLEDGE的session是未定义的变量,应该使用静态常量Session.CLIENT_ACKNOWLEDGE(注意大写类名)。
4. 调整依赖兼容性
Spring Boot 2.5.0对Java 17的支持并不完善,建议升级Spring Boot到2.6+版本(官方从2.6开始正式支持Java17),同时确保Azure Service Bus JMS依赖版本匹配:
在pom.xml中更新依赖:
<dependency> <groupId>com.azure.spring</groupId> <artifactId>spring-boot-starter-azure-servicebus-jms</artifactId> <version>3.0.0</version> <!-- 适配Spring Boot 2.6+和Java17 --> </dependency>
完整修正示例代码
import javax.jms.Connection; import javax.jms.ConnectionFactory; import javax.jms.Session; import com.azure.spring.servicebus.jms.ServiceBusJmsConnectionFactory; import com.azure.spring.servicebus.jms.ServiceBusJmsConnectionFactorySettings; public class ServiceBusJmsExample { public static void main(String[] args) throws Exception { String connectionString = "<CONNECTION_STRING>"; String clientId = "<CLIENT_ID>"; ServiceBusJmsConnectionFactorySettings settings = new ServiceBusJmsConnectionFactorySettings(); ConnectionFactory factory = new ServiceBusJmsConnectionFactory(connectionString, settings); Connection connection = factory.createConnection(); connection.setClientId(clientId); connection.setExceptionListener(new MyExceptionHandler()); connection.start(); // 非事务性会话 + 自动确认,匹配RECEIVE AND DELETE模式 Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); // 后续创建MessageConsumer等操作... } }
额外注意点
- 检查Azure Service Bus连接字符串的权限:确保拥有
Listen权限,且订阅名称正确。 - 重试异常可能是连接配置错误导致:比如clientId重复(每个连接的clientId需唯一),或者网络防火墙阻止了Service Bus的端口(默认5671/5672)。
内容的提问来源于stack exchange,提问作者Joe1988
相关产品推荐
相关产品推荐

