2010-06-10 15 views
9

Digamos que tiene una aplicación que conecta 3 sistemas externos diferentes. Necesita actualizar algo en todo 3. En caso de falla, necesita deshacer las operaciones. Esto no es algo difícil de implementar, pero dice que la operación 3 falla, y al retroceder, la reversión de la operación 1 falla. Ahora el primer sistema externo está en un estado inválido ...Operaciones atómicas en varios sistemas externos sin transacción

Estoy pensando que una posible solución es cerrar la aplicación y forzar una reparación manual del sistema externo, pero de nuevo ... Puede que ya tenga usó esta información (y tal vez por eso falló), o es posible que no tengamos acceso suficiente. ¡O tal vez ni siquiera sea una buena forma de revertir la acción!

¿Existen algunas buenas maneras de manejar estos casos?

EDIT: Algunos detalles de la aplicación ..

Es una aplicación web de usuario múltiples. La mayor parte del trabajo se realiza con trabajos programados (a través de Quartz.Net), por lo que la mayoría de las operaciones se ejecuta en su propio hilo. Sin embargo, algunas acciones de usuario deberían desencadenar trabajos que actualicen varios sistemas. Los sistemas externos son algo inestables.

estaba pensando en cambiar la aplicación a utilizar la unidad de mando y de patrón de trabajo

+0

¿Están fijos los sistemas externos? ¿O puedes modificarlos? – bmargulies

Respuesta

1

Commit dos fases (2PC) podría ser adecuado aquí.

La primera fase consiste en conseguir que las distintas bases de datos acuerden que están dispuestas a seguir adelante con el compromiso. En su ejemplo, la base de datos 1 no continuará con la escritura hasta que esté seguro de que las tres bases de datos informaron que la transacción será posible.

Esto se compara con el proceso que describe que es un enfoque "optimista": la base de datos 1 asumirá que la transacción debe continuar hasta que aprenda lo contrario y se vea forzada a deshacerse.

+0

Gracias. Es un poco lo que ya tengo usando un UnitOfWork con Execute, Commit y Rollback que almacena comandos que tienen CanProcess Do y Undo. – simendsjo

0

Dependiendo del tamaño de la aplicación (solo usuario frente a la empresa), el cierre de la aplicación podría ser una mala idea.

Antes que nada, sugiero guardar el estado inicial de la información que se está cambiando en las 3 aplicaciones externas para el almacenamiento local de su propia aplicación. Eso significa que al menos puede determinar cuál es el estado de reversión en caso de que la aplicación se bloquee/la retrotracción falle/etc. Una vez que la transacción se haya realizado correctamente, puede eliminar esta información.

Qué hacer cuando una de las operaciones falla depende de la funcionalidad de los 3 sistemas externos. Supongamos que uno de estos sistemas contiene datos de empleados. Cerrar la aplicación simplemente porque la dirección de un empleado es incorrecta debido a una transacción fallida es excesiva. Es mucho mejor simplemente verificar el registro de transacciones fallidas (es decir, el almacenamiento local en el que guardó los estados iniciales de las 3 aplicaciones externas) cada vez que se accede a los datos de un empleado. Si los datos de ese empleado se marcan como no válidos, genere un error que indique que el registro no se encuentra en estado válido y no se puede recuperar.

Sin embargo, si todo el sistema externo se desorganiza por una transacción fallida, entonces sí, no hay nada que pueda hacer aquí, pero apague su aplicación hasta que se solucione el problema.

1

¿Desea explicar cómo puede fallar la reversión de la operación 1?

El estado al que se aspira es uno que haya estado antes, por lo que debe ser lógicamente consistente.Puede haber problemas transitorios como fallas en la red, pero podría ser el caso que la mejor forma de lidiar con eso es volver a intentarlo hasta que los problemas desaparezcan.

Si el problema es que las transacciones subsiguientes han bloqueado o cambiado los datos mientras tanto, entonces usted tiene un problema mucho más grande: sus transacciones no son atómicas y su devolución puede causar que el resultado de otras transacciones se vuelva inválido.

0

La respuesta de Oddthinking es buena, pero limitada porque es muy difícil de realmente fiable hacer un 2PC. Esto se conoce desde hace bastante tiempo en la comunidad de la informática distribuida, aunque muchas personas hacen todo lo posible para ignorarlo.

Si está interesado en profundizar en esta área, el Paxos consensus algorithm es un buen lugar para comenzar. Y tenga en cuenta que este es un problema sorprendentemente difícil, precisamente por los problemas a los que alude y por el hecho de que es realmente imposible construir un sistema de mensajería verdaderamente confiable que pueda entregar un mensaje en un tiempo limitado. (Para comprender por qué es cierto, considere que someone with a backhoe podría eliminar todos los enlaces de red entre las diversas partes que se comunican ...)

Sospecho que la solución real es diseñar la arquitectura del sistema en general y cómo implementar los cambios en él. que la pérdida de comunicaciones en un área no es catastrófica. Esto puede o no ser fácil de hacer, dependiendo de los detalles exactos.

Cuestiones relacionadas