Mensagens JMS transacionais. Mito ou verdade?

11 respostas
L

Diz a lenda que em um contexto transacional, uma mensagem JMS só é enviada após o commit da transação corrente.

Pois bem, nenhuma versão do Jboss 4.x.x faz isso e eu não encontrei nada na spec do JMS dizendo que é esse o comportamento, então já estava me convencendo que isso é realmente um mito.

Porém, lendo o artigo do Guerra na Mundo Java deste mês, novamente ele tocou no assunto dizendo que o comportamento esperado é realmente só enviar a mensagem após o commit da transação.

Então, isso é mito ou verdade? :smiley:

Se é verdade, em que app server isso acontece?

No JBoss 4.x.x isso definitivamente não acontece, e inclusive já veio até consultor da Jboss aqui tentar fazer isso funcionar e nada.

11 Respostas

sergiotaborda

lavh:
Diz a lenda que em um contexto transacional, uma mensagem JMS só é enviada após o commit da transação corrente.
.

Não. O que acontece é que a mensagem só é aknowledge quando a transação comita. A mensagem é enviada normalmente. (liás, se não fosse não teria fluxo de informação dentro da transação)

P.S. É uma missconception comum achar que só manda quando comita.

Rubem_Azenha

O que eu já vi é um MDB usando a mesma transação do Session Bean que o chamou, mas isso é através de 2PC.
Se não me engano, o antigo BES (Borland Enterprise Server) fazia isso automaticamente quando o tipo de transação do MDB era required (e não requires new) e estivesse configurado o 2PC.

W

O que está acontecendo no JBoss aí é que a mensagem está sendo entregue ao servidor antes do commit ou o MDB processa a mensagem antes do commit?

L

O MDB processa a mensagem antes do commit.

W

Estranho, pelo que eu sei isso não deveria acontecer, quer dizer que se a transação der um rollback depois de enviar a mensagem, a mensagem será enviada e processada mesmo assim ? No JBoss eu não sei como funciona mas no Glassfish isso não acontece.

Rubem_Azenha

Só para ter certeza que eu não entendi errado:

Você quer que um Session Bean com transação aberta mande uma mensagem para uma fila JMS (sendo que tem um MDB escutando essa fila JMS) e essa mensagem seja enviada apenas quando a transação for commitada?

Nunca ouvi falar nisso não, será que não da pra fazer isso com AOP?
Ou, no pior dos casos, cria um Session Bean com transação requresNew, coloca sua lógica lá, e coloca o código de chamar esse Session Bean + código de mandar mensagem JMS dentro de outro Session Bean com transação required.

W

Seria isso sim, imagine que o MDB faz uma modificação em uma BD, e após isso a transação do Session Bean que enviou uma mensagem para essa fila, acontece um rollback? Os dados no banco de dados ficariam inconsistentes. Se a mensagem que o MDB processa realmente acontecer na hora que o Bean envia essa mensagem para a fila, poderia então ser feito um request/reply(com QueueReceiver.receive), coisa que só é possível se o bean não estiver usando transação.

W

Olha essa parte do ejbCore que fala sobre transações e JMS:

“The Bean Provider should not make use of the JMS request/reply paradigm(sending of a JMS message, followed by the synchronous receipt of a reply to that message)within a single transaction. Because a JMS message is typically not delivered to its final destination until the transaction commits, the receipt of the reply within the same transaction will not take place.”

C

Texto interessante que recebi hoje (via RSS) da JBoss:
http://www.odi.ch/prog/jms-tx.php

W

Exatamente, e como fala nesse artigo: “Using JTA means that messages you send from a session bean get really sent only with the commit (along with your DB changes etc.), and are discarded if you rollback.”

Lavh, verifica se a criação da Connection e Session estão sendo feitas dento do contexto da transação que envia a mensagem(e não em um @PostConstruct, por exemplo).

Sefo

Olá a todos.

Estamos com uma aplicação em fase final e só agora nos deparamos com esse probelma.

De um lado criamos um lote, salvamos ele no banco e enviamos uma mensagem JMS com o valor do lote gerado.
Quando meu MDB tenta processa o lote, ele ainda não foi “commitado” no banco e portanto não é encontrado.

O servidor usado é o JBoss 4.2.x e nessa altura do campeonato não é possível troca-lo.

Gostaria de saber se alguem tem uma dica/ideia de como resolver esse problema.

Sergio, se importaria de me explicar melhor o que vc quis dizer nessas partes destacadas.

Grato.

Criado 18 de dezembro de 2009
Ultima resposta 21 de jan. de 2010
Respostas 11
Participantes 6