DZone
Thanks for visiting DZone today,
Edit Profile
  • Manage Email Subscriptions
  • How to Post to DZone
  • Article Submission Guidelines
Sign Out View Profile
  • Post an Article
  • Manage My Drafts
Over 2 million developers have joined DZone.
Log In / Join
Please enter at least three characters to search
Refcards Trend Reports
Events Video Library
Refcards
Trend Reports

Events

View Events Video Library

Zones

Culture and Methodologies Agile Career Development Methodologies Team Management
Data Engineering AI/ML Big Data Data Databases IoT
Software Design and Architecture Cloud Architecture Containers Integration Microservices Performance Security
Coding Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks
Culture and Methodologies
Agile Career Development Methodologies Team Management
Data Engineering
AI/ML Big Data Data Databases IoT
Software Design and Architecture
Cloud Architecture Containers Integration Microservices Performance Security
Coding
Frameworks Java JavaScript Languages Tools
Testing, Deployment, and Maintenance
Deployment DevOps and CI/CD Maintenance Monitoring and Observability Testing, Tools, and Frameworks

Last call! Secure your stack and shape the future! Help dev teams across the globe navigate their software supply chain security challenges.

Modernize your data layer. Learn how to design cloud-native database architectures to meet the evolving demands of AI and GenAI workloads.

Releasing software shouldn't be stressful or risky. Learn how to leverage progressive delivery techniques to ensure safer deployments.

Avoid machine learning mistakes and boost model performance! Discover key ML patterns, anti-patterns, data strategies, and more.

Related

  • Leveraging Datadog and Solace PubSub+ for Improved Visibility in Event-Driven Systems
  • Event-Driven Order Processing Program
  • Event-Driven Hello World Program
  • A Robust Distributed Payment Network With Enchanted Audit Functionality - Part 2: Spring Boot, Axon, and Implementation

Trending

  • How the Go Runtime Preempts Goroutines for Efficient Concurrency
  • How to Practice TDD With Kotlin
  • Immutable Secrets Management: A Zero-Trust Approach to Sensitive Data in Containers
  • AI, ML, and Data Science: Shaping the Future of Automation
  1. DZone
  2. Data Engineering
  3. Data
  4. Saga Pattern | How to Implement Business Transactions Using Microservices - Part I

Saga Pattern | How to Implement Business Transactions Using Microservices - Part I

In this article, you'll learn about the Saga Pattern for distributed transactions and how it can help businesses working with microservices.

By 
Denis W S Rosa user avatar
Denis W S Rosa
·
Feb. 06, 18 · Tutorial
Likes (45)
Comment
Save
Tweet
Share
46.8K Views

Join the DZone community and get the full member experience.

Join For Free

One of the most powerful types of transactions is called a Two-Phase Commit, which is in summary when the commit of a first transaction depends on the completion of a second. It is useful especially when you have to update multiple entities at the same time, like confirming an order and updating the stock at once.

However, when you are working with microservices, for example, things get more complicated. Each service is a system apart with its own database, and you no longer can leverage the simplicity of local two-phase-commits to maintain the consistency of your whole system.

When you lose this ability, RDBMS becomes quite a bad choice for storage, as you could accomplish the same "single entity atomic transaction" but dozens of times faster by just using a NoSQL database like Couchbase. That is why the majority of companies working with microservices are also using NoSQL.

To exemplify this problem, consider the following high-level microservices architecture of an e-commerce system:

In the example above, one can't just place an order, charge the customer, update the stock, and send it to delivery all in a single ACID transaction. To execute this entire flow consistently, you would be required to create a distributed transaction.

We all know how difficult it is to implement anything distributed, and transactions, unfortunately, are no exception. Dealing with transient states, eventual consistency between services, isolations, and rollbacks are scenarios that should be considered during the design phase.

Fortunately, we have already come up with some good patterns for it, as we have been implementing distributed transactions for over twenty years now. The one that I would like to talk about today is called the Saga pattern.

The Saga Pattern

One of the most well-known patterns for distributed transactions is called Saga. The first paper about it was published back in 1987, and it has been a popular solution since then.

A Saga is a sequence of local transactions where each transaction updates data within a single service. The first transaction is initiated by an external request corresponding to the system operation, and then each subsequent step is triggered by the completion of the previous one.

Using our previous e-commerce example, in a very high-level design, a Saga implementation would look like the following:

There are a couple of different ways to implement a saga transaction, but the two most popular are:

  1. Events/Choreography: When there is no central coordination, each service produces and listens to the other service's events and decides if an action should be taken or not.
  2. Command/Orchestration: When a coordinator service is responsible for centralizing the saga's decision making and sequencing business logic.

Let's go a little bit deeper into each implementation to understand how they work.

Events/Choreography

In the Events/Choreography approach, the first service executes a transaction and then publishes an event. This event is listened to by one or more services, which execute local transactions and publish (or don't publish) new events.

The distributed transaction ends when the last service executes its local transaction and does not publish any events, or the event published is not heard by any of the saga's participants.

Let's see how it would look in our e-commerce example:


  1. Order Service saves a new order, set the state as pending and publish an event called ORDER_CREATED_EVENT.
  2. The Payment Service listens to ORDER_CREATED_EVENT, charge the client and publish the event BILLED_ORDER_EVENT.
  3. The Stock Service listens to BILLED_ORDER_EVENT, update the stock, prepare the products bought in the order and publish ORDER_PREPARED_EVENT.
  4. Delivery Service listens to ORDER_PREPARED_EVENT and then pick up and deliver the product. At the end, it publishes an ORDER_DELIVERED_EVENT
  5. Finally, Order Service listens to ORDER_DELIVERED_EVENT and set the state of the order as concluded.

In the case above, if the state of the order needs to be tracked, Order Service could simply listen to all events and update its state.

Rollbacks in distributed transactions

Rolling back a distributed transaction does not come for free. Normally you have to implement another operation/transaction to compensate for what has been done before.

Suppose that Stock Service has failed during a transaction. Let's see what the rollback would look like:


  1. Stock Service produces PRODUCT_OUT_OF_STOCK_EVENT;
  2. Both Order Service and Payment Service listen to the previous message:
    1. Payment Service refund the client.
    2. Order Service set the order state as failed.

Note that it is crucial to define a common shared ID for each transaction, so whenever you throw an event, all listeners can know right away which transaction it refers to.

Benefits and Drawbacks of Saga's Event/Choreography Design

Events/Choreography is a natural way to implement Saga's pattern; it is simple, easy to understand, does not require much effort to build, and all participants are loosely coupled as they don't have direct knowledge of each other. If your transaction involves 2 to 4 steps, it might be a very good fit.

However, this approach can rapidly become confusing if you keep adding extra steps in your transaction, as it is difficult to track which services listen to which events. Moreover, it also might add a cyclic dependency between services, as they have to subscribe to one another's events.

Finally, testing would be tricky to implement using this design. In order to simulate the transaction behavior, you should have all services running.

In the next post, I will explain how to address most of the problems with Saga's Events/Choreography approach using another Saga implementation called Command/Orchestration.

In the meantime, if you have any questions, feel free to ask me at @deniswsrosa.

microservice Event

Published at DZone with permission of Denis W S Rosa, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

Related

  • Leveraging Datadog and Solace PubSub+ for Improved Visibility in Event-Driven Systems
  • Event-Driven Order Processing Program
  • Event-Driven Hello World Program
  • A Robust Distributed Payment Network With Enchanted Audit Functionality - Part 2: Spring Boot, Axon, and Implementation

Partner Resources

×

Comments
Oops! Something Went Wrong

The likes didn't load as expected. Please refresh the page and try again.

ABOUT US

  • About DZone
  • Support and feedback
  • Community research
  • Sitemap

ADVERTISE

  • Advertise with DZone

CONTRIBUTE ON DZONE

  • Article Submission Guidelines
  • Become a Contributor
  • Core Program
  • Visit the Writers' Zone

LEGAL

  • Terms of Service
  • Privacy Policy

CONTACT US

  • 3343 Perimeter Hill Drive
  • Suite 100
  • Nashville, TN 37211
  • support@dzone.com

Let's be friends:

Likes
There are no likes...yet! 👀
Be the first to like this post!
It looks like you're not logged in.
Sign in to see who liked this post!