Pergunta

Eu tenho um cenário muito simples envolvendo um base de dados e a Jms em um servidor de aplicativos (Glassfish). O cenário é morto simples:

1. an EJB inserts a row in the database and sends a message.
2. when the message is delivered with an MDB, the row is read and updated. 

O problema é que às vezes o a mensagem é entregue antes que a inserção seja cometida no banco de dados. Isso é realmente compreensível se considerarmos o protocolo de confirmação de 2 fases:

1. prepare JMS
2. prepare database
3. commit JMS
4. ( tiny little gap where message can be delivered before insert has been committed)
5. commit database

Eu discuti esse problema com outros, mas a resposta sempre foi: "Estranho, deve funcionar fora da caixa".

Minhas perguntas são então:

  • Como poderia funcionar fora da caixa?
  • Meu cenário parece bastante simples, por que não há mais pessoas com problemas semelhantes?
  • Estou fazendo algo errado? Existe uma maneira de resolver esse problema corretamente?

Aqui estão um pouco mais de detalhes sobre minha compreensão do problema:

Esse problema de tempo existe apenas se o participante for tratado nesta ordem. Se o 2PC tratar os participantes na ordem inversa (primeiro banco de dados, depois o corretor de mensagens), isso deve ficar bem. O problema estava acontecendo aleatoriamente, mas completamente reproduzível.

Não encontrei nenhuma maneira de controlar a ordem dos participantes nas transações distribuídas nas especificações JTA, JCA e JPA, nem na documentação do Glassfish. Poderíamos assumir que eles serão alistados na transação distribuída de acordo com a ordem quando forem usados, mas com um ORM como JPA, é difícil saber quando os dados são liberados e quando a conexão do banco de dados é realmente usada. Qualquer ideia?

Foi útil?

Solução

Você está experimentando a condição clássica de corrida XA 2-PC. Isso acontece em ambientes de produção.

Há 3 coisas chegando à minha mente.

  1. Última otimização do agente, onde o JDBC é o recurso não-XA. (Perca a semântica da recuperação)
  2. Tenha JMS Time-T-DeLike. (Deliberadamente perder tempo real)
  3. Construa as tentativas no código JDBC. (Menos efeito na funcionalidade)

O WebLogic tem essa otimização de LLR evita esse problema e oferece todas as garantias do XA.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top