activemq用message确认消息的问题

首先,用auto模式,在onmessage之前就已经确认消息了。这时候如果onmessage中报错了,消息也不会重发。这是org.springframework.jms.listener.DefaultMessageListenerContainer类源码中的注释片段:“AUTO_ACKNOWLEDGE" mode, this container applies automatic message acknowledgment before listener execution, with no redelivery in case of an exception。大概意思就是我说的auto模式,容器自动在执行listener之前就自动确认消息了,遇到异常也不会重发了。

如果是client或者是trans模式,这个在执行完后会确认,如果报错,消息就不会被确认,会触发重发机制。org.springframework.jms.listener.AbstractMessageListenerContainer类中部分代码,可以看到消息被确认。

	/**
	 * Execute the specified listener,
	 * committing or rolling back the transaction afterwards (if necessary).
	 * @param session the JMS Session to operate on
	 * @param message the received JMS Message
	 * @throws JMSException if thrown by JMS API methods
	 * @see #invokeListener
	 * @see #commitIfNecessary
	 * @see #rollbackOnExceptionIfNecessary
	 * @see #convertJmsAccessException
	 */
	protected void doExecuteListener(Session session, Message message) throws JMSException {
		if (!isAcceptMessagesWhileStopping() && !isRunning()) {
			if (logger.isWarnEnabled()) {
				logger.warn("Rejecting received message because of the listener container " +
						"having been stopped in the meantime: " + message);
			}
			rollbackIfNecessary(session);
			throw new MessageRejectedWhileStoppingException();
		}

		try {
			invokeListener(session, message);
		}
		catch (JMSException ex) {
			rollbackOnExceptionIfNecessary(session, ex);
			throw ex;
		}
		catch (RuntimeException ex) {
			rollbackOnExceptionIfNecessary(session, ex);
			throw ex;
		}
		catch (Error err) {
			rollbackOnExceptionIfNecessary(session, err);
			throw err;
		}
		commitIfNecessary(session, message);
	}
	/**
	 * Perform a commit or message acknowledgement, as appropriate.
	 * @param session the JMS Session to commit
	 * @param message the Message to acknowledge
	 * @throws javax.jms.JMSException in case of commit failure
	 */
	protected void commitIfNecessary(Session session, Message message) throws JMSException {
		// Commit session or acknowledge message.
		if (session.getTransacted()) {
			// Commit necessary - but avoid commit call within a JTA transaction.
			if (isSessionLocallyTransacted(session)) {
				// Transacted session created by this container -> commit.
				JmsUtils.commitIfNecessary(session);
			}
		}
		else if (message != null && isClientAcknowledge(session)) {
			message.acknowledge();
		}
	}

这里的重发机制就是这个方法,主要是rollback和recover方法

	/**
	 * Perform a rollback, handling rollback exceptions properly.
	 * @param session the JMS Session to rollback
	 * @param ex the thrown application exception or error
	 * @throws javax.jms.JMSException in case of a rollback error
	 */
	protected void rollbackOnExceptionIfNecessary(Session session, Throwable ex) throws JMSException {
		try {
			if (session.getTransacted()) {
				if (isSessionLocallyTransacted(session)) {
					// Transacted session created by this container -> rollback.
					if (logger.isDebugEnabled()) {
						logger.debug("Initiating transaction rollback on application exception", ex);
					}
					JmsUtils.rollbackIfNecessary(session);
				}
			}
			else if (isClientAcknowledge(session)) {
				session.recover();
			}
		}
		catch (IllegalStateException ex2) {
			logger.debug("Could not roll back because Session already closed", ex2);
		}
		catch (JMSException ex2) {
			logger.error("Application exception overridden by rollback exception", ex);
			throw ex2;
		}
		catch (RuntimeException ex2) {
			logger.error("Application exception overridden by rollback exception", ex);
			throw ex2;
		}
		catch (Error err) {
			logger.error("Application exception overridden by rollback error", ex);
			throw err;
		}
	}

 

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
要使用 ActiveMQ 接收消息,你需要按照以下步骤进行操作: 1. 首先,你需要在代码中引入 ActiveMQ 的相关包,可以使用 Maven 等工具进行依赖管理。 2. 接下来,你需要创建一个 ActiveMQ 的连接工厂对象,该对象用于创建连接。 ``` ConnectionFactory connectionFactory = new ActiveMQConnectionFactory("tcp://localhost:61616"); ``` 这里的参数是 ActiveMQ 的连接地址和端口号。 3. 然后,你需要使用连接工厂创建一个连接对象。 ``` Connection connection = connectionFactory.createConnection(); ``` 4. 接着,你需要启动连接。 ``` connection.start(); ``` 5. 然后,你需要创建一个会话对象,用于发送和接收消息。 ``` Session session = connection.createSession(false, Session.AUTO_ACKNOWLEDGE); ``` 这里的参数表示会话是否开启事务和消息确认模式。 6. 接下来,你需要创建一个目标对象,用于发送和接收消息。 ``` Destination destination = session.createQueue("queueName"); ``` 这里的参数是消息队列的名称。 7. 然后,你需要创建一个消息消费者对象,用于接收消息。 ``` MessageConsumer consumer = session.createConsumer(destination); ``` 8. 最后,你可以编写一个循环,用于从队列中接收消息并进行处理。 ``` while (true) { Message message = consumer.receive(); // 处理消息 } ``` 这里的代码会一直循环接收消息,直到程序关闭。 以上就是使用 ActiveMQ 接收消息的步骤。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值