Rollback em JMS

1 resposta
J

Estou desenvolvendo uma aplicação usando JMS (MDB) e preciso fazer um controle para caso seja lançada uma exceção no tratamento da mensagem a mesma não seja removida da fila, ou seja, ela deve permanecer na fila para que possa ser processada novamente mais tarde.
Esta fila foi criada em OracleAQ e quando acesso ela em uma aplicação standAlone (sem MDB apenas para teste) setando a sessão como CLIENT_ACKNOWLEDGE, eu consigo fazer com a mensagem não seja removida da fila, para isto basta apenas não chamar o metodo message.acknowledge() caso ocorra algum erro.
Meu problema é que gostaria de ter este mesmo comportamento com MDB, porém não estou conseguindo.
Pelo que eu li, quando é usado MDB, o Container cria uma transação quando o método onMessage() é chamado e caso seja lançada uma exceção de RuntimeException, o próprio Container fica responsavel por fazer o rollback, e entendo eu manter a mensagem na fila, porém este cenário não esta ocorrendo comigo.
Abaixo segue minha classe MDB, onde estou lançando uma exception propositalmente para realizar este teste, porém qdo executo o código, a mensagem é tida como processada e removida da Fila.

@MessageDriven(
activationConfig = {
    @ActivationConfigProperty(
    propertyName="ConnectionFactoryJndiName", propertyValue="java:comp/resource/myProvedorRecursos/QueueConnectionFactories/myQCF"),
    @ActivationConfigProperty(
    propertyName="DestinationName", propertyValue="java:comp/resource/myProvedorRecursos/Queues/NGEM_TO_INTEGRA_QUEUE"),
    @ActivationConfigProperty(
    propertyName="DestinationType", propertyValue="javax.jms.Queue")
})
public class MessageDrivenBean implements MessageListener {

    //@TransactionAttribute(value=TransactionAttributeType.REQUIRES_NEW) 
    public void onMessage(Message message) {
        try {
          TextMessage textMessage= (TextMessage)message;
          if(textMessage.getText().contains("TESTANDO2")){
              System.out.println("Erro ao processar mensagem.");
              throw new Exception("Erro lendo mensagem 2 da Fila");
          }
          System.out.println("  Dequeued text-message = " + textMessage.getText());
          //  message.setJMSRedelivered();   
        }
        catch (Exception e) {
            e.printStackTrace();
            throw new EJBException(e);
        }
    }
}

O servidor de aplicação que estou utilizando é o IAS, onde foi configurado o provedor de recursos que faz interface com as filas OracleAQ. Se alguem souber me dizer o que estou fazendo de errado no código ou alguma configuração a mais que deva ser feita no IAS eu agradeço.

1 Resposta

J

Bom pessoal consegui resolver meu problema. Vou postar aqui a solução caso alguem passe pela mesma coisa.
A solução foi simples, bastou adicionar explicitamente as annotations @TransactionManagement(value=TransactionManagementType.CONTAINER) para a classe e @TransactionAttribute(value=TransactionAttributeType.REQUIRED) para o método onMessage.

Caso alguém queira saber mais detalhes sobre isto a solução foi encontrada no sitehttp://e-docs.bea.com/wls/docs92/ejb/message_beans.html#wp1162058
Neste site tem uma OBS que fala o seguinte:

Ou seja, por default ele não usa transação. Mesmo o tópico falando sobre o WebLogic Server este se mostrou igual no IAS.

Criado 27 de abril de 2009
Ultima resposta 28 de abr. de 2009
Respostas 1
Participantes 1