Patrón Compensating Transaction (Transacción de compensación)Compensating Transaction pattern

Deshace el trabajo realizado mediante una serie de pasos, que conjuntamente definen una operación definitivamente coherente, si uno o varios de los pasos termina en error.Undo the work performed by a series of steps, which together define an eventually consistent operation, if one or more of the steps fail. Las operaciones que siguen el modelo de coherencia definitiva se suelen encontrar en aplicaciones hospedadas en la nube que implementan flujos de trabajo y procesos empresariales complejos.Operations that follow the eventual consistency model are commonly found in cloud-hosted applications that implement complex business processes and workflows.

Contexto y problemaContext and problem

Las aplicaciones que se ejecutan en la nube con frecuencia modifican datos.Applications running in the cloud frequently modify data. Estos datos pueden estar repartidos entre varios orígenes de datos mantenidos en diferentes ubicaciones geográficas.This data might be spread across various data sources held in different geographic locations. Para evitar la contención y mejorar el rendimiento en un entorno distribuido, una aplicación no debe intentar proporcionar una fuerte coherencia transaccional.To avoid contention and improve performance in a distributed environment, an application shouldn't try to provide strong transactional consistency. Por el contrario, la aplicación debe implementar coherencia definitiva.Rather, the application should implement eventual consistency. En este modelo, una operación empresarial habitual consta de una serie de distintos pasos.In this model, a typical business operation consists of a series of separate steps. Mientras se realizan estos pasos, la vista general del estado del sistema puede ser incoherente, pero cuando se completa la operación y se han ejecutado todos los pasos, el sistema debe volverse de nuevo coherente.While these steps are being performed, the overall view of the system state might be inconsistent, but when the operation has completed and all of the steps have been executed the system should become consistent again.

En Data Consistency Primer (Manual básico de coherencia de datos) se proporciona información sobre por qué las transacciones distribuidas no se escalan bien, y se incluyen los principios del modelo de coherencia definitiva.The Data Consistency Primer provides information about why distributed transactions don't scale well, and the principles of the eventual consistency model.

Una de las dificultades del modelo de coherencia definitiva es cómo tratar con un paso que ha dado error.A challenge in the eventual consistency model is how to handle a step that has failed. En este caso, podría ser necesario deshacer todo el trabajo realizado en los pasos anteriores de la operación.In this case it might be necessary to undo all of the work completed by the previous steps in the operation. Sin embargo, no basta simplemente con revertir los datos, ya que es posible que otras instancias simultáneas de la aplicación hayan cambiado.However, the data can't simply be rolled back because other concurrent instances of the application might have changed it. Incluso en casos donde una instancia simultánea no ha modificado los datos, deshacer un paso puede no ser solo cuestión de restaurar el estado original.Even in cases where the data hasn't been changed by a concurrent instance, undoing a step might not simply be a matter of restoring the original state. Podría ser necesario aplicar varias reglas específicas el negocio (consulte el sitio web de viajes descrito en la sección de ejemplos).It might be necessary to apply various business-specific rules (see the travel website described in the Example section).

Si una operación que implementa coherencia definitiva abarca varios almacenes de datos heterogéneos, para deshacer los pasos de la operación será necesario visitar cada almacén de datos por turnos.If an operation that implements eventual consistency spans several heterogeneous data stores, undoing the steps in the operation will require visiting each data store in turn. El trabajo realizado en cada almacén de datos se debe deshacer de manera confiable para impedir que el sistema permanezca incoherente.The work performed in every data store must be undone reliably to prevent the system from remaining inconsistent.

No todos los datos afectados por una operación que implementa la coherencia definitiva se pueden mantener en una base de datos.Not all data affected by an operation that implements eventual consistency might be held in a database. En un entorno de arquitectura orientada a servicios (SOA), una operación podría invocar una acción en un servicio y provocar un cambio en el estado que mantiene ese servicio.In a service oriented architecture (SOA) environment an operation could invoke an action in a service, and cause a change in the state held by that service. Para deshacer la operación, este cambio de estado también se debe deshacer.To undo the operation, this state change must also be undone. Esto puede suponer invoca nuevamente el servicio y realizar otra acción que invierta los efectos de la primera.This can involve invoking the service again and performing another action that reverses the effects of the first.

SoluciónSolution

La solución pasa por implementar una transacción de compensación.The solution is to implement a compensating transaction. Los pasos de una transacción de compensación deben deshacer los efectos de los pasos de la operación original.The steps in a compensating transaction must undo the effects of the steps in the original operation. Una transacción de compensación no puede reemplazar simplemente el estado actual por el estado en que se encontraba el sistema al principio de la operación porque este enfoque podría sobrescribir los cambios realizados por otras instancias simultáneas de una aplicación.A compensating transaction might not be able to simply replace the current state with the state the system was in at the start of the operation because this approach could overwrite changes made by other concurrent instances of an application. En lugar de ello, debe ser un proceso inteligente que tenga en cuenta el trabajo realizado por instancias simultáneas.Instead, it must be an intelligent process that takes into account any work done by concurrent instances. Normalmente, este proceso será específico de la aplicación y dependerá de la naturaleza del trabajo realizado por la operación original.This process will usually be application specific, driven by the nature of the work performed by the original operation.

Un enfoque común es usar un flujo de trabajo para implementar una operación de coherencia definitiva que requiere compensación.A common approach is to use a workflow to implement an eventually consistent operation that requires compensation. Mientras se realiza la operación original, el sistema registra información acerca de cada paso y cómo se puede deshacer el trabajo realizado por ese paso.As the original operation proceeds, the system records information about each step and how the work performed by that step can be undone. Si se produce un error en la operación en cualquier momento, el flujo de trabajo retrocede a los pasos completados y realiza el trabajo que invierte cada paso.If the operation fails at any point, the workflow rewinds back through the steps it's completed and performs the work that reverses each step. Tenga en cuenta que es posible que una transacción de compensación no tenga que deshacer el trabajo en el orden inverso exacto de la operación original, algunos de los pasos para deshacer podrían realizarse en paralelo.Note that a compensating transaction might not have to undo the work in the exact reverse order of the original operation, and it might be possible to perform some of the undo steps in parallel.

Este enfoque es similar a la estrategia de Sagas que se describe en el blog de Clemens Vasters.This approach is similar to the Sagas strategy discussed in Clemens Vasters’ blog.

Una transacción de compensación es asimismo una operación de coherencia definitiva y también podría dar error.A compensating transaction is also an eventually consistent operation and it could also fail. El sistema debería poder reanudar la transacción de compensación en el punto de error y continuar.The system should be able to resume the compensating transaction at the point of failure and continue. Como podría ser necesario repetir un paso que no se pudo realizar, los pasos de una transacción de compensación deben definirse como comandos idempotentes.It might be necessary to repeat a step that's failed, so the steps in a compensating transaction should be defined as idempotent commands. Para más información, consulte los patrones de idempotencia en el blog de Jonathan Oliver.For more information, see Idempotency Patterns on Jonathan Oliver’s blog.

En algunos casos, puede que no sea posible recuperarse de un paso que ha dado error si no es mediante intervención manual.In some cases it might not be possible to recover from a step that has failed except through manual intervention. En estas situaciones el sistema debe generar una alerta y proporcionar tanta información como sea posible sobre el motivo del error.In these situations the system should raise an alert and provide as much information as possible about the reason for the failure.

Problemas y consideracionesIssues and considerations

Tenga en cuenta los puntos siguientes al decidir cómo implementar este patrón:Consider the following points when deciding how to implement this pattern:

Puede que no sea fácil determinar el momento en el que ha dado error un paso de una operación que implementa coherencia definitiva.It might not be easy to determine when a step in an operation that implements eventual consistency has failed. Es posible que un paso no genere error inmediatamente, pero podría dar lugar a un bloqueo.A step might not fail immediately, but instead could block. Podría ser necesario implementar algún tipo de mecanismo de tiempo de espera.It might be necessary to implement some form of time-out mechanism.

-La lógica de compensación no se generaliza fácilmente.-Compensation logic isn't easily generalized. Una transacción de compensación es específica de la aplicación.A compensating transaction is application specific. Se basa en la aplicación que tiene información suficiente para poder deshacer los efectos de cada paso en una operación con errores.It relies on the application having sufficient information to be able to undo the effects of each step in a failed operation.

Los pasos de una transacción de compensación se deben definir como comandos idempotentes.You should define the steps in a compensating transaction as idempotent commands. De esta forma, se puede repetir los pasos si la transacción, de compensación propiamente dicha produce error.This enables the steps to be repeated if the compensating transaction itself fails.

La infraestructura que administra los pasos de la operación original debe ser resistente, y lo mismo la transacción de compensación.The infrastructure that handles the steps in the original operation, and the compensating transaction, must be resilient. En este sentido, no debe perder la información necesaria para compensar un paso de error y debe ser capaz de supervisar de forma confiable el progreso de la lógica de compensación.It must not lose the information required to compensate for a failing step, and it must be able to reliably monitor the progress of the compensation logic.

Una transacción de compensación no devuelve necesariamente los datos del sistema al estado que tenía al inicio de la operación original.A compensating transaction doesn't necessarily return the data in the system to the state it was in at the start of the original operation. Lo que hace es compensar el trabajo realizado mediante los pasos que se realizaron correctamente antes de que la operación produjera un error.Instead, it compensates for the work performed by the steps that completed successfully before the operation failed.

El orden de los pasos de la transacción de compensación no tiene que ser necesariamente el opuesto exacto de los pasos de la operación original.The order of the steps in the compensating transaction doesn't necessarily have to be the exact opposite of the steps in the original operation. Por ejemplo, un almacén de datos podría ser más sensible a las incoherencias que otro y, por tanto, los pasos de la transacción de compensación que deshacen los cambios realizados en este almacén deberían realizarse en primer lugar.For example, one data store might be more sensitive to inconsistencies than another, and so the steps in the compensating transaction that undo the changes to this store should occur first.

Una manera de aumentar la probabilidad de que la actividad general tenga éxito, consiste en colocar un bloqueo a corto plazo basado en el tiempo de espera sobre cada recurso que es necesario para realizar una operación y obtener esos recursos con antelación.Placing a short-term timeout-based lock on each resource that's required to complete an operation, and obtaining these resources in advance, can help increase the likelihood that the overall activity will succeed. El trabajo debe realizarse solo después de que todos los recursos se han adquirido.The work should be performed only after all the resources have been acquired. Todas las acciones se deben finalizar antes de que expiren los bloqueos.All actions must be finalized before the locks expire.

Considere la posibilidad de usar una lógica de reintentos que sea más flexible de lo habitual para reducir los errores que desencadenan una transacción de compensación.Consider using retry logic that is more forgiving than usual to minimize failures that trigger a compensating transaction. Si se produce un error en una operación que implementa coherencia definitiva, intente abordar el error como una excepción transitoria y repita el paso.If a step in an operation that implements eventual consistency fails, try handling the failure as a transient exception and repeat the step. Únicamente detenga la operación e inicie una transacción de compensación si un paso da error de forma repetida o irrecuperable.Only stop the operation and initiate a compensating transaction if a step fails repeatedly or irrecoverably.

Muchas de las dificultades de implementar una transacción de compensación son las mismas que las que se experimentan al implementar coherencia definitiva.Many of the challenges of implementing a compensating transaction are the same as those with implementing eventual consistency. Consulte la sección sobre las consideraciones para implementar coherencia definitiva en el Data Consistency Primer (Manual básico de coherencia de datos) para más información.See the section Considerations for Implementing Eventual Consistency in the Data Consistency Primer for more information.

Cuándo usar este patrónWhen to use this pattern

Use este patrón únicamente en operaciones que se deben deshacer si se produce un error.Use this pattern only for operations that must be undone if they fail. Si es posible, diseñe soluciones que eviten la complejidad de exigir transacciones de compensación.If possible, design solutions to avoid the complexity of requiring compensating transactions.

EjemploExample

Un sitio web de viajes permite que los clientes reserven itinerarios.A travel website lets customers book itineraries. Un único itinerario podría constar de vuelos y hoteles.A single itinerary might comprise a series of flights and hotels. Un cliente que viaja de Seattle a Londres y, luego, a París podría realizar los siguientes pasos al crear un itinerario:A customer traveling from Seattle to London and then on to Paris could perform the following steps when creating an itinerary:

  1. Reservar una plaza en el vuelo F1 de Seattle a Londres.Book a seat on flight F1 from Seattle to London.
  2. Reservar una plaza en el vuelo F2 de Londres a París.Book a seat on flight F2 from London to Paris.
  3. Reservar una plaza en el vuelo F3 de París a Seattle.Book a seat on flight F3 from Paris to Seattle.
  4. Reservar una habitación en el hotel H1 en Londres.Reserve a room at hotel H1 in London.
  5. Reservar una habitación en el hotel H2 en París.Reserve a room at hotel H2 in Paris.

Estos pasos constituyen una operación de coherencia definitiva, aunque cada paso es una acción independiente.These steps constitute an eventually consistent operation, although each step is a separate action. Por lo tanto, mientras se realizan estos pasos, el sistema deben registrar también las operaciones de contador necesarias para deshacer cada paso en caso de que el cliente decida cancelar el itinerario.Therefore, as well as performing these steps, the system must also record the counter operations necessary to undo each step in case the customer decides to cancel the itinerary. Los pasos necesarios para realizar las operaciones de contador se pueden ejecutar entonces como una transacción de compensación.The steps necessary to perform the counter operations can then run as a compensating transaction.

Tenga en cuenta que los pasos de la transacción de compensación podrían no ser el opuesto exacto de los pasos originales, y que la lógica de cada paso de la transacción de compensación debe tener en cuenta las reglas específicas del negocio.Notice that the steps in the compensating transaction might not be the exact opposite of the original steps, and the logic in each step in the compensating transaction must take into account any business-specific rules. Por ejemplo, cancelar la reserva de una plaza en un vuelo podría no dar derecho al cliente a una devolución completa del dinero abonado.For example, unbooking a seat on a flight might not entitle the customer to a complete refund of any money paid. En la figura se ilustra la generación de una transacción de compensación para deshacer una transacción de ejecución prolongada con el fin de reservar un itinerario de viaje.The figure illustrates generating a compensating transaction to undo a long-running transaction to book a travel itinerary.

Generación de una transacción de compensación para deshacer una transacción de ejecución prolongada para reservar un itinerario de viaje

Nota

Es posible que los pasos de la transacción de compensación se realicen en paralelo, en función de cómo haya diseñado la lógica de compensación de cada paso.It might be possible for the steps in the compensating transaction to be performed in parallel, depending on how you've designed the compensating logic for each step.

En muchas soluciones empresariales, que un único paso produzca error no significa que haya que restaurar todo el sistema mediante una transacción de compensación.In many business solutions, failure of a single step doesn't always necessitate rolling the system back by using a compensating transaction. Por ejemplo, si—después de haber reservado los vuelos F1 y F2, F3 en el escenario del sitio web de viajes—el cliente no puede reservar una habitación en el hotel H1, es preferible ofrecer al cliente una habitación en un hotel diferente de la misma ciudad en lugar de cancelar los vuelos.For example, if—after having booked flights F1, F2, and F3 in the travel website scenario—the customer is unable to reserve a room at hotel H1, it's preferable to offer the customer a room at a different hotel in the same city rather than canceling the flights. El cliente todavía puede decidir cancelarlos (en cuyo caso la transacción de compensación se ejecuta y se deshacen las reservas realizadas en los vuelos F1, F2 y F3), pero esta decisión debe tomarla el cliente y no el sistema.The customer can still decide to cancel (in which case the compensating transaction runs and undoes the bookings made on flights F1, F2, and F3), but this decision should be made by the customer rather than by the system.

Los patrones y las directrices siguientes también pueden ser importantes a la hora de implementar este modelo:The following patterns and guidance might also be relevant when implementing this pattern:

  • Data Consistency Primer (Manual básico de coherencia de datos).Data Consistency Primer. El patrón Compensating Transaction se usa a menudo para deshacer operaciones que implementan el modelo de coherencia definitiva.The Compensating Transaction pattern is often used to undo operations that implement the eventual consistency model. En este manual se proporciona información sobre las ventajas e inconvenientes de la coherencia definitiva.This primer provides information on the benefits and tradeoffs of eventual consistency.

  • Patrón Scheduler-Agent-Supervisor.Scheduler-Agent-Supervisor pattern. Describe cómo implementar sistemas resistentes que realicen operaciones empresariales en las que se usen recursos y servicios distribuidos.Describes how to implement resilient systems that perform business operations that use distributed services and resources. En ocasiones, podría ser necesario deshacer el trabajo realizado por una operación mediante el uso de una transacción de compensación.Sometimes, it might be necessary to undo the work performed by an operation by using a compensating transaction.

  • Patrón Retry.Retry pattern. Las transacciones de compensación pueden resultar costosas de realizar, y una forma de reducir su uso podría ser implementar una directiva efectiva de reintento de las operaciones con error siguiendo el patrón Retry.Compensating transactions can be expensive to perform, and it might be possible to minimize their use by implementing an effective policy of retrying failing operations by following the Retry pattern.