java - transaction - ¿Cómo diseñar una transacción distribuida global(ninguna base de datos)? ¿Puede JTA utilizar para ninguna transacción de db?
atomikos (3)
Creo que esta es una pregunta bastante común: ¿cómo colocar la lógica de mi negocio en una transacción global en un entorno de sistemas distribuidos? Cito un ejemplo, tengo un TaskA que contiene parejas de sub tareas:
TaskA {subtask1, subtask2, subtask3 ...}
Cada una de estas subtareas puede ejecutarse en una máquina local o remota, espero que la Tarea A se ejecute de forma atómica (éxito o fracaso) mediante una transacción. Cada subtarea tiene una función de retrotracción, una vez que TaskA piensa que la operación falla (porque falla una de las subtareas), llama a cada función de retrotracción de las subtareas. De lo contrario, TaskA comete la transacción completa.
Para hacer esto, sigo el patrón de transacción "Prueba de auditoría" para tener un registro para cada subtarea, para que TaskA pueda conocer los resultados de la operación de las subtareas y luego decida revertir o confirmar. Esto suena simple, sin embargo, la parte difícil es cómo asociar cada subtarea a la transacción global.
Cuando TaskA comienza, comienza una transacción global sobre la cual la subtarea no sabe nada. Para que la subtarea sea consciente de ello, tengo que pasar el contexto de la transacción a cada invocación de la subtarea. ¡Esto es realmente terrible! Mi subtarea puede ejecutarse en un nuevo hilo o ejecutarse en remoto enviando un mensaje a través del agente AMQP, es difícil consolidar el camino de la propagación del contexto.
Hice algunas investigaciones como "Patrones de transacción - Una colección de cuatro patrones relacionados con transacciones", "Transacciones comprobadas en un entorno de paso de mensajes asíncronos", ninguno de ellos resuelve mi problema. O bien no tienen un ejemplo práctico o no resuelven el problema de la propagación del contexto.
Me pregunto cómo la gente resuelve esto. ya que este tipo de transacción debe ser común en el software empresarial.
¿Es X / Open XA solo la solución para esto? Puedo ayudar a JTA aquí (no he considerado a JTA como la mayoría de las cosas relacionadas con la transacción de la base de datos, y estoy usando Spring, no quiero involucrar a otro servidor de aplicaciones Java EE en mi software).
¿Puede algún experto compartir algunos pensamientos conmigo? gracias.
Conclusión
Arjan y Martin dieron muy buenas respuestas, gracias. Finalmente no fui con este camino. Después de más investigación, elegí otro patrón " CheckPoint " 1 .
Al analizar mi requerimiento, descubrí que mi intención de "Auditar el patrón de transacción de prueba" es saber a qué nivel ha procedido la operación; si falla, puedo reiniciarlo en el lugar con error después de volver a cargar algún contexto. En realidad esto no es una transacción, no retrocedió otros pasos exitosos después de una falla. Esta es la esencia del patrón CheckPoint. Sin embargo, estudiar cosas de transacciones distribuidas me hace aprender muchas cosas interesantes. Aparte de lo que Arjan y Martin han mencionado. También sugiero que las personas que están investigando esta área echen un vistazo a CORBA, que es un protocolo bien conocido para sistemas distribuidos.
Podría hacer lo siguiente (similar a su estrategia de punto de control):
TaskA se ejecuta en una transacción JTA (local) e intenta reservar los recursos necesarios antes de que delegue en sus subtareas
Las invocaciones de subtareas se realizan a través de JMS / XA: si el paso 1 falla, no se activará ninguna subtarea y si el paso 1 se confirma, las invocaciones de JMS se recibirán en cada subtarea
Las subtareas (re) intentan procesar su mensaje de invocación con un conjunto de límites de entrega máxima de JMS (consulte la documentación de su proveedor de JMS sobre cómo hacerlo)
Configure una "cola de mensajes no entregados" para cualquier falla en 3.
Esto funciona, asumiendo que:
-tentarse en el paso 3 tiene sentido
-hay un poco de intervención humana necesaria para los mensajes en la cola de mensajes no entregados
Si esto no es aceptable, también hay TCC: http://www.atomikos.com/Main/DownloadWhitepapers?article=TccForRestApi.pdf : esto puede verse como un patrón de "reserva" para los servicios REST.
Espero que esto ayude
Chico
Tienes razón, necesitas soporte de confirmación en dos fases gracias a un administrador de transacciones XA proporcionado por la API de JTA.
Que yo sepa, Spring no proporciona una implementación de gestor de transacciones. El JtaTransactionManager solo delega en la implementación existente que generalmente se proporciona desde las implementaciones de JavaEE.
Por lo tanto, tendrá que conectar una implementación JTA en Spring para realizar un trabajo efectivo. Aquí hay algunas propuestas:
Luego, deberá implementar su administrador de recursos para admitir la confirmación en dos fases. En los mundos JavaEE, consiste en un adaptador de recursos empaquetado como un archivo RAR. Dependiendo del tipo de recurso, los siguientes aspectos son para leer / implementar:
- Interfaz XAResource
- Arquitectura del conector Java JCA principalmente si se trata de una conexión remota
- Servicio de transacciones JTS si se requiere propagación de transacciones entre nodos
Como ejemplos, te recomiendo que mires las implementaciones para el problema clásico de "transacciones con archivos":
- el administrador de archivos transaccionales de JBoss Transactions
- Proyecto XADisk
Si desea escribir su propio recurso transaccional, de hecho necesita implementar un XAResource y dejar que se una a una transacción en curso, manejar las solicitudes de preparación y confirmación del administrador de transacciones, etc.
Las fuentes de datos son los recursos transaccionales más conocidos, pero como se mencionó, no son los únicos. Usted ya mencionó a los proveedores de JMS. Una variedad de soluciones de caché (por ejemplo, Infinispan) también son recursos transaccionales.
Implementar XAResources y trabajar con la parte de nivel inferior de la API de JTA y el JTS (Java Transaction Service) de nivel inferior no es una tarea para los débiles de corazón. La API puede ser arcaica y todo el proceso está apenas documentado.
La razón es que las aplicaciones empresariales normales que crean sus propios recursos transaccionales son extremadamente raras. Todo el punto de ser transaccional es realizar una acción atómica para un observador externo.
Ser observable en la gran mayoría de los casos significa que los efectos de la acción están presentes en una base de datos. Casi todas y cada una de las fuentes de datos ya son transaccionales, por lo que el caso de uso está completamente cubierto.
Otro efecto observable es si un mensaje ha sido enviado o no, y eso también está totalmente cubierto por las soluciones de mensajería existentes.
Finalmente, la actualización de un mapa de memoria (en todo el clúster) es otro efecto observable, que también está cubierto por los principales proveedores de caché.
Existe un remanente de la demanda de efectos transaccionales cuando se opera con sistemas de información empresarial externos (EIS), y como regla general, los proveedores de dichos sistemas proporcionan conectores conscientes de las transacciones.
El escalofrío de los casos de uso que quedan es tan pequeño que aparentemente nadie se molestó en escribir mucho al respecto. Hay algunos blogs por ahí que cubren algunos de los conceptos básicos, pero se dejará mucho para su propia experimentación.
Intente verificar por sí mismo si realmente necesita recorrer este camino y si uno de los recursos transaccionales existentes no puede satisfacer su necesidad.