Fila de Mensagens Mortas

O que acontece quando há uma exceção em um recebedor registrado em uma fila?

Por exemplo:

@MessageDriven(activationConfig = {
  @ActivationConfigProperty(propertyName = "destinationLookup", propertyValue = "jms/FILA"),
  @ActivationConfigProperty(propertyName = "destinationType", propertyValue = "javax.jms.Queue")
})
public class RecebedorMDB implements MessageListener {
  public void onMessage(Message msg) {
    throw new RuntimeException("Erro!");
  }
}

A classe acima é um Message Driven Bean (MDB) registrado em FILA que lança uma exceção não checada ao receber uma mensagem.

Se verificarmos a fila, a mensagem foi consumida. Só que aconteceu um erro!

De acordo com a especificação de mensageria do Java EE, o JMS (Java Message Service), um message listener que retorna uma RuntimeException é considerado um erro de programação e terá comportamento indefinido.

Aí entram detalhes da implementação: no HornetQ, o MOM (Message Oriented Middleware) do Wildfly 8.x.x, envia as mensagens que ocasionaram uma exceção para a fila DLQ. O nome vem da sigla para Dead Letter Queue, ou fila de mensagens mortas. É como se fosse um lugar para onde as mensagens vão morrer. O conceito também é conhecido como Dead Letter Channel ou Dead Message Queue.

Mas, na verdade, o recomendado é que os message listeners ou MDBs tratem todas as exceções. Uma boa solução é criarmos DLQs específicas para cada caso excepcional do processo de negócio. Ao detectarmos uma exceção, enviamos a mensagem para a DLQ correspondente.

Anúncios