Implementing Complex Distributed (Business) Transactions with Saga Pattern (and workflows)

I talked about microservices at two conferences last week. In both opportunities, the attendees asked me about how to implement the Saga pattern. So, I decided to blog about it.

What is a Saga?

From the microservices.io:

A saga is a sequence of local transactions. Each local transaction updates the state (database) and publishes a message or event to trigger the next local transaction in the saga. If a local transaction fails because it violates a business rule then the saga executes a series of compensating transactions that undo the changes that were made by the preceding local transactions.

The original idea is pretty old and comes from this article.

The implementation I recommend is known as “Orchestration-based saga.”

Saga as a Flow

I like to think Sagas as a long-running flow. Using BPMN (Business Process Modeling Notation), we could represent the preceding Saga as follows:

 

The good thing about representing Sagas as workflows is that we can run it using a workflow engine. So the workflow engine can act as the Saga Execution Coordinator.

What workflow engine I should/could use?

Like everything, the correct answer is: “It depends.” There are several options you could use. Some options are potent (and expensive). Also, there are a lot of lightweight and cheap alternatives. The right choice depends on your project.

I have been working (a lot) in a lightweight workflow engine library that you could use in your projects to solve a lot of problems (including “how to implement Sagas,” of course). It is still under development, but it will be ready to use soon.

Here is a preview of how you would configure your saga using my library:

var model = ProcessModel.Create()
  .AddEventCatcher<CreateNewOrderCommand>("start")
  .AddActivity<CreateOrderActivity>("CreateOrder")
  .AddActivity<CancelOrderActitivity>("CancelOrder")
  .AttachAsCompensationActivity("CancelOrder", "CreateOrder")
  .AddActivity<CreateOrderActivity>("ReserveProducts")
  .AddActivity<CancelOrderAcitivity>("CancelReservation")
  .AttachAsCompensationActivity("ReserveProducts", "CancelReservation")
  .AddActivity<RequestPaymentActivity>("RequestPayment")
  .AddActivity<CancelPaymentActivity>("CancelPayment")
  .AttachAsCompensationActivity("RequestPayment", "CancelPayment")
  .AddActivity<RequestDeliveryActivity>("RequestDelivery")
  .AddEventThrower("end")
  .AddSequenceFlow("start", 
  "CreateOrder", "ReserveProducts", 
  "RequestPayment", "RequestDelivery",
  "end"
  );

var models = new InMemoryProcessModelsStore(model);
var instances = new InMemoryProcessInstancesStore();

var manager = new ProcessManager(models, instances);

Nice, huh?

Let me know if you are implementing microservices and need help. It would be a pleasure to help your company. Also, I would love to help you to start using my library (again, it is under development and source code is on Github).

Compartilhe este insight:

Elemar Júnior

Sou fundador e CEO da EximiaCo e atuo como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

Elemar Júnior

Sou fundador e CEO da EximiaCo e atuo como tech trusted advisor ajudando diversas empresas a gerar mais resultados através da tecnologia.

Mais insights para o seu negócio

Veja mais alguns estudos e reflexões que podem gerar alguns insights para o seu negócio:

Implementing a good caching strategy is fundamental to achieve good performance. Besides that, it is not a trivial task. There...
Neste post, apresento o conceito de “Dívida Técnica” (não é débito, é dívida). Explico por que nem sempre elas são...
This is the first of a series of blog posts sharing some knowledge about how to develop a real-world software...
This is another post about how to implement a basic Search Engine. Previously, I explained: how to produce an inverted...
The example which motivated this post comes from the excellent book Designing Distributed Systems by Brendan Burns (co-founder of the...
Nessa última semana, Fernando Neiva apresentou um compilado de nossas lições aprendidas implementando Kanban na Guiando. Aqui, compartilhamos o registro...