JMS: Rollback em Mensagem

4 respostas
mcampelo

Alo Pessoal,

tenho uma aplicação StandAlone que fica escutando uma fila. A cada nova mensagem, é feito um insert em um banco de dados.

O que fazer se o insert falhar?

Cada mensagem da fila deve obrigatoriamente gerar um registro em minha tabela.

Como é feito o controle de erro quando trabalhamos com fila? É possível dar um rollback na mensagem e fazer com que ela volte automaticamente para a fila?

Minha dúvida é se há uma maneira automática de fazer isso ou se vou precisar postar a mensagem na fila novamente na munheca mesmo.

Muito obrigado,

4 Respostas

T

Sim, no JMS existe o conceito de rollback. Basta para isso capturar o MessageDrivenContext e chamar o metodo setRollbackOnly no caso de falha.

Desta forma o Container reinfilerara a mensagem na fila e reprocessara ela.

Agora isso apresenta um perigo em potencial, o que eh chamado de poison message. Uma mensagem que apresenta uma falha e volta para a fila, quando for processada novamente eh bem provavel que apresente a mesma falha. Ai ela fica nesse pingue pongue. O ideal mesmo seria verificar qual a causa da falha, no caso, por que o insert falhou e entao consertar no metodo mesmo.

Existem alguns containers que proveem algumas alternativas interessantes para mensagens que voltam para a fila, com por exemplo: Time to redeliver, Redelivery count e Exception destination. A primeira eh um tempo de espera para o proximo redeliver, o segundo eh o numero maximo de tentativas de deliver e o ultimo indica uma fila opcional onde as mensagens que nao foram entregues no numero maximo de tentativas sao infileiradas.

mcampelo

Alo Tanque,

“tanque”:
Sim, no JMS existe o conceito de rollback. Basta para isso capturar o MessageDrivenContext e chamar o metodo setRollbackOnly no caso de falha.

O problema é que tenho uma aplicação StandAlone que implementa o MessageListener. Não estou trabalhando com MDB.

Eu vi que o QueueSession possui o método rollBack(), mas isso faria rollback em TODAS as mensagens que meu listener recebe.

Estou trabalhando com Weblogic e ele dá suporte para isso. Inclusive, já está configurado.

Abraços,

mcampelo

Cheguei ao seguinte código:

public void onMessage(Message msg) {
   if (bean.getCodigo()==0) {
         qsession.commit();
   } else {
         qsession.rollback();
   }
}

A minha dúvida é sobre quem esse commit() ou rollback() vai agir. Apenas sobre a mensagem que está chegando no onMessage() ou pode interferir em outras mensagens?

T

Olha teria que testar. Acredito eu , que apos a mensagem ter sido Comitada, ela nao volta mais para a fila nao. Achei um exemplo bem do que tu queres fazer, na javaworld, da uma olhada:


O exemplo processa mensagens numeradas de 1 ate 9. Na mensagem 5 da um commit e na mensagem 9 da um rollback. Depois do rollback as mensagens a partir da 6 nao foram reprocessadas. As anteriores a 5 nao retornaram ao reprocessamento.
O codigo em questao usa um negocio de createQueueSession, que nao sei qual a necessidade. Bem, vale como exemplo.

Criado 2 de fevereiro de 2004
Ultima resposta 3 de fev. de 2004
Respostas 4
Participantes 2