alibaba/spring-cloud-alibaba · error · MessagingException

TransactionMQProducer must have a TransactionListener !!!

Error message

TransactionMQProducer must have a TransactionListener !!! 

What it means

In handleMessageInternal, when the producer is a TransactionMQProducer the handler looks up a TransactionListener bean by name (`mqProducerProperties.getTransactionListener()`) via RocketMQBeanContainerCache. If none resolves, it throws MessagingException - transactional sends require a listener to drive local-execute and check-back.

Source

Thrown at spring-cloud-alibaba-starters/spring-cloud-starter-stream-rocketmq/src/main/java/com/alibaba/cloud/stream/binder/rocketmq/integration/outbound/RocketMQProducerMessageHandler.java:176

	}

	@Override
	public boolean isRunning() {
		return running;
	}

	@Override
	protected void handleMessageInternal(Message<?> message) {
		try {
			org.apache.rocketmq.common.message.Message mqMessage = RocketMQMessageConverterSupport
					.convertMessage2MQ(destination.getName(), message);
			SendResult sendResult;
			if (defaultMQProducer instanceof TransactionMQProducer translateMQProducer) {
				TransactionListener transactionListener = RocketMQBeanContainerCache
						.getBean(mqProducerProperties.getTransactionListener(),
								TransactionListener.class);
				if (transactionListener == null) {
					throw new MessagingException(
							"TransactionMQProducer must have a TransactionListener !!! ");
				}
				translateMQProducer.setTransactionListener(transactionListener);
				if (log.isDebugEnabled()) {
					log.debug("send transaction message ->{}", mqMessage);
				}
				sendResult = defaultMQProducer.sendMessageInTransaction(mqMessage,
						message.getHeaders().get(RocketMQConst.USER_TRANSACTIONAL_ARGS));
			}
			else {
				if (log.isDebugEnabled()) {
					log.debug("send message ->{}", mqMessage);
				}
				sendResult = this.send(mqMessage, this.messageQueueSelector,
						message.getHeaders(), message);
			}
			if (log.isDebugEnabled()) {
				log.debug("the message has sent,message={},sendResult={}", mqMessage,

View on GitHub (pinned to 115d590110)

Solutions

  1. Register a TransactionListener bean and reference its name via `spring.cloud.stream.rocketmq.bindings.<output>.producer.transactionListener=<beanName>`.
  2. If you don't need transactions, set `producerType: Normal` (default).
  3. Verify the bean is visible to RocketMQBeanContainerCache (registered in the application context).

Example fix

// before
spring:
  cloud:
    stream:
      rocketmq:
        bindings:
          txOut:
            producer:
              producerType: Trans   # no transactionListener -> [131]
// after
@Bean("myTxListener")
TransactionListener myTxListener() { /* ... */ return /* ... */; }
// yaml:
spring:
  cloud:
    stream:
      rocketmq:
        bindings:
          txOut:
            producer:
              producerType: Trans
              transactionListener: myTxListener
Defensive patterns

Strategy: validation

Validate before calling

// Pre-flight: transactional producers must resolve a listener.
if (RocketMQProducerProperties.ProducerType.Trans.equalsName(mqProducerProperties.getProducerType())) {
    TransactionListener tl = RocketMQBeanContainerCache
        .getBean(mqProducerProperties.getTransactionListener(), TransactionListener.class);
    Assert.notNull(tl, "transactionListener bean required for producerType=Trans (avoids [131])");
}

Type guard

// Type guard narrowing the producer type before send.
boolean transactional = defaultMQProducer instanceof TransactionMQProducer;
boolean hasListener = RocketMQBeanContainerCache
    .getBean(mqProducerProperties.getTransactionListener(), TransactionListener.class) != null;
if (transactional && !hasListener) {
    throw new IllegalStateException("Trans producer requires a TransactionListener bean");
}

Prevention

When it happens

Trigger: producerType is set to Trans (so a TransactionMQProducer is built) but no TransactionListener bean is registered/resolvable under the configured `transactionListener` name.

Common situations: Set `producerType: Trans` without providing a `transactionListener` bean; bean name typo; the listener bean lives in a context RocketMQBeanContainerCache does not scan; a transaction example copied incompletely.

Related errors


AI-assisted analysis of alibaba/spring-cloud-alibaba@115d590110 (2026-08-14). Data as JSON: /api/errors/eb3f53b154753edc. Report an issue: GitHub.