database - example - jms teoria
Entrega de mensaje JMS antes de que se confirme la transacción. (1)
Usted está experimentando la clásica condición de carrera XA 2-PC. Ocurre en entornos de producción.
Hay 3 cosas que vienen a mi mente.
- Optimización del último agente donde JDBC es el recurso que no es XA. (Perder la semántica de recuperación)
- Tener JMS Time-to-Deliver. (Perder deliberadamente en tiempo real)
- Generar reintentos en código JDBC. (Menor efecto en la funcionalidad)
Weblogic tiene esta optimización de LLR, evita este problema y le ofrece todas las garantías de XA.
Tengo un escenario muy simple que involucra una base de datos y un JMS en un servidor de aplicaciones (Glassfish). El escenario es muerto simple:
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.
El problema es que a veces el mensaje se entrega antes de que la inserción se haya confirmado en la base de datos. Esto es realmente comprensible si consideramos el protocolo de confirmación 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
He discutido este problema con otros , pero la respuesta siempre fue: "Extraño, debería funcionar fuera de la caja" .
Mis preguntas son entonces:
- ¿Cómo podría funcionar fuera de la caja?
- Mi escenario parece bastante simple, ¿por qué no hay más personas con problemas similares?
- ¿Estoy haciendo algo mal? ¿Hay alguna manera de resolver este problema correctamente?
Aquí hay un poco más de detalles sobre mi comprensión del problema:
Este problema de tiempo solo existe si el participante se trata en este orden. Si el 2PC trata a los participantes en el orden inverso (la base de datos primero y luego el intermediario de mensajes) debería estar bien. El problema estaba sucediendo al azar pero completamente reproducible.
No encontré ninguna forma de controlar el orden de los participantes en las transacciones distribuidas en las especificaciones JTA, JCA y JPA ni en la documentación de Glassfish. Podríamos suponer que se incluirán en la transacción distribuida según el orden cuando se usen, pero con un ORM como JPA, es difícil saber cuándo se eliminan los datos y cuándo se usa realmente la conexión de la base de datos. ¿Alguna idea?