Uno de los fundamentos de SOA es la composición de servicios. Es decir, crear servicios de más alto nivel a partir de otros servicios más sencillos. Hasta aquí todo bien, pero… ¿que pasa con el servicio compuesto si uno de esos servicios más sencillo falla?.
Si hacemos un servicio compuesto que llama a un primer servicio que modifica el estado de los datos y luego llamamos al segundo, y este falla… ¿que ocurre?. Si consideramos este servicio compuesto como un «todo», tendríamos que deshacer también lo que ha hecho el primer servicio ¿no?.
Tradicionalmente, este deshacer o rollback de varias lógicas de negocio se ha delegado al protocolo de transaccionalidad distribuida (Two Phase Commit) que implementan la mayoría de las bases de datos y servidores de aplicaciones empresariales. De esta manera, los dos servicios e «incluyen» dentro de una transacción (aunque se ejecute en dos máquinas diferentes) y cuando se produce un error, al hacer rollback, automáticamente se deshacen los cambios que hayan hecho estos dos servicios.
¿Pero que pasa en SOA? decimos que los servicios deben tener bajo o ningún acoplamiento entre sí. ¿Como se lleva eso con el hecho de que los dos sistemas implicados en este caso deben entender un protocolo común de transaccionalidad distribuida?. No parece que haya mucho desacoplamiento.
El stack WS-* define un estándar para realizar esto a nivel del web services. Por desgracia, no hay uno si no dos (al menos de estos estándares). Y si no tenemos mucha suerte, cada fabricante usará uno distinto. Esto es lo que pasa por ejemplo con el servidor de IBM y el de Software AG.
¿Qué solución tenemos a esto? pues según los patrones de SOA, la compensación. El concepto es muy simple, por cada servicio de negocio que haga algo, tendremos otro servicio para deshacerlo (una especie de Control-Z o undo a nivel de servicio).
Por desgracia, esto no es un deshacer directo a nivel de tabla de base de datos como lo es un rollback, implica ejecutar lógicas de negocio y por lo tanto, los servicios para deshacer o para «compensar» necesitan diseñarse e implementarse de la misma manera que sus contrapartes.
Así pues, y como conclusión, cuando diseñemos un sistema SOA, habría que tener en cuenta estos dos puntos:
- No podemos confiar en que todos los sistemas (servidores de aplicaciones, bases de datos) soporten el protocolo de transaccionalidad distribuida e incluso, si lo hacen, que implementen el mismo
- La transaccionalidad distribuida va en contra del desacoplamiento que deben tener los serviiocs
- Tenemos que pensar desde el mismo diseño que muchos de los servicios de negocio que hagamos deben tener su servicio de deshacer. Quizás esto implique duplicar el número de servicios a implementar.
Aquí puedes ver un artículo (en inglés) muy extenso sobre este tema.
24/09/2013 at 22:44
Hola
Me parece una solución mala, doble trabajo más tiempo más costes, doble mantenimiento. No término de ver esa solución lo que haces para ahorrar por un lado lo rompes por otro.
Un saludo y muy interesante como siempre.
24/09/2013 at 22:48
El problema es que muchas veces no queda otro remedio ya que la transaccionalidad distribuida no funciona (por ejemplo con un servicio java y otro .net). En los procesos de negocio, no queda otra solución que tener servicios de compensación porque un proceso puede durar semanas y la transacción de base de datos no puede durar más que unos segundos como mucho.
27/09/2013 at 17:54
Efectivamente es la única alternativa que queda, sobre todo porque empleando 2PC generas bloqueos simultáneos en todos los sistemas participantes de la transaccionalidad (qué no tienen porqué ser solamente dos).
Buen artículo.
04/01/2014 at 22:52
En weblogic 11G/12C es posible utilizar ws-at (transacciones atómicas) como parte de las opciones avanzadad en la pila de ws-*
El punto es que para transacciones distribuídas síncronas (que nos sean procesos de negocios de mediana o larga duración), este escenario funciona:no hay qie realizar servicios de compensación. El commit y el rollback son explícitos. Glassfish también responde a esto. Adicionalmente weblogic para este servicio de uso de ws-at puede usarse con ws de ibm webspjer, ms biztalk y jboss.
31/07/2015 at 22:10
Creo que el arte de SOA se basa en el diseño, como mencionan en el articulo, creo que la compensación sería lo mas sano mediante un buen diseño SOA, tratando de minimizar este tipo de complejidades y por ende, tratar de hacer lo menos servicios complejos a partir de servicios atomicos transaccionales, no desaparecerlos, pero si minimizarlos mientras se pueda. ¿Cómo? Se pueden crear servicios complejos y atomicos cuantas veces se desee cuando no son transaccionales, pero en los que si se necesita transaccionabilidad, se debe revisar caso por caso y ver que estrategia usar. Por ejemplo, dejando que el servicio complejo maneje la transaccion y los servicios atomicos solo proporcionen calculos sin almacenar nada en BD. En los casos que no se pueda hacer esto, se debería aplicar la compensación. Para esto existimos los arquitectos de aplicaciones para poder presentar un buen diseño ante las complejidades que se presentan en cada proyecto. SOA realmente es bello pero si presenta algunas dificultades y hacer grandes aplicaciones basadas en SOA, es un arte.