Saga: The New Era of Transactions in A Microservices Architecture
Saga: The New Era of Transactions in A Microservices Architecture
microservices architecture
Giovanni Marigi - Senior Middleware Consultant
Mauro Vocale - Solution Architect
Monitoring Invocation
MyService
Logging Elasticity
Authentication Resilience
Pipeline
MICROSERVICES DILEMMA: How to handle transactions?
Every microservice has its own state and a local store (RDBMS, NoSQL, file store, ...)
But you still want that a business process spanning several services to be
consistent and correct regardless of the level of decomposition of your
application.
Why distributed transactions don’t work
Traditional distributed transactions are implemented using a two-phase commit,
briefly 2PC.
● You don’t have a single shared store anymore, every service has its own data
store (micro-db)
● A microservices architecture involves many parties, realized using different
technologies that adhere to different specifications: 2PC implicitly assumes
closely coupled environment
● Synchronization and isolation reduces performance and scalability.
● A business function potentially lasting for hours or days: lock strategy doesn't
work well in long duration activities
Distributed transactions
book a ticket
Ticket Service Insurance Service
book a ticket
XA resource XA resource
Simple rule:
2PC would try to reserve both the ticket and the insurance
at the same time. If it doesn’t succeed, none of them will be
booked.
Microservices: eventual consistency
Consistency states that the entire software system should be in a valid state.
2PC guarantees the consistency with a pessimistic approach; all the changes must be
done at the same time or rollback.
Ticket service and Insurance service will try to book independently. In case of failure in
one of the two, the other one will be canceled.
Eventual consistency is not easy achieve and there is no a magic box out there.
Saga Pattern
Le Radeau de la Méduse -
Théodore Géricault, 1818-19
Saga Pattern: overview
Saga is the de facto solution to guarantee consistency in a microservices architecture.
Saga is not a new pattern [1] and it can be applied also in traditional monolithic
architectures.
“For specific applications, it may be possible to alleviate the problems by relaxing the
requirement that an LLT be executed as an atomic action. In other words, without
sacrificing the consistency of the database, it may be possible for certain LLTs to release
their resources before they complete, thus permitting other waiting transactions to
proceed”
Saga usually performs better than distributed transactions and doesn’t require all the
services to be available at the same time.
[1]
https://www.cs.cornell.edu/andru/cs711/2002fa/reading/sagas.pdf
Transaction ACID Properties
● Atomicity: this property guarantees that each transaction is treated as a single "unit", which
either succeeds completely, or fails completely
● Consistency: this property is related to the logical consistency of the data. When a new
transaction starts, it must ensure that the data maintains a state of logical consistency,
regardless of the final outcome
● Isolation: this property ensures that concurrent execution of transactions leaves the database
in the same state that would have been obtained if the transactions were executed
sequentially
● Durability: this property guarantees that all of the changes made during a transaction, once it
is committed, it must be persistent and definitive, even in the case of system crashes
Saga Pattern: ACD
Saga is a series of local transactions; every local transaction happens within the
boundary of the (micro)-service.
Saga has ACD characteristics, distributed transactions ACID characteristics [1]; the
real challenge is to deal with the lack of isolation (I) in an elegant and effective way.
Compensations are the actions to apply when a failure happens to leave the system in
an inconsistent state.
Compensations actions must be idempotent; they might be called more than once.
[1]
https://www.ibm.com/support/knowledgecenter/en/SSGMCP_5.4.0/product-overvi
ew/acid.html
Saga Pattern: the lack of I
Lack of isolation causes:
● Dirty reads: a transaction read data from a row that is currently modified by another
running transaction
● Lost updates: two different transactions trying to update the same “data”. One of
them doesn’t see the new value when trying to update
If another Saga instance starts, it must evaluate the existing *_PENDING states and
pay attention on them.
compensation
Ticket Saga (Payment Error)
Book
Book
ticket Payment
ticket
insurance
book a ticket
Payment
Cancel Cancel error
ticket ticket insurance
Saga Choreography vs Orchestration
How to implement a Saga and how to coordinate the execution of local transactions within
a microservice?
Two approaches:
Decentralized approach, all the systems work independently and they cooperate for a
common goal (without having knowledge on what is it).
Events are sent to a message broker system (Apache Kafka, ActiveMQ, ...) and they
contain a correlation-id
Easy to code but difficult to govern it. It’s difficult to monitor and reconstruct the
overall status of a Saga.
Saga Choreography PAYMENT_ACCEPTED event
must be handled by
Insurance Service
Ticket Service
Message Broker System
ticket topic
Insurance
Service
insurance table
ORDER_CREATED
TICKET_CREATED
INSURANCE_BOOKED_PENDING
order topic
INSURANCE_BOOKED
Ticket Service
payment topic
ticket table
Payment payment table
PAYMENT_ACCEPTED Service
TICKET_BOOKED_PENDING PAYMENT_CONFIRMED
TICKET_BOOKED
Saga Choreography PAYMENT_REFUSED event
must be handled by
Insurance Service
Ticket Service
Message Broker System
ticket topic
Insurance
Service
insurance table
ORDER_CREATED
TICKET_CREATED
INSURANCE_BOOKED_PENDING
order topic
INSURANCE_PAYMENT_REFUSED
Ticket Service
payment topic
ticket table
Payment payment table
PAYMENT_REFUSED Service
TICKET_BOOKED_PENDING PAYMENT_CONFIRMED
TICKET_PAYMENT_REFUSED
Saga Choreography
We don’t want to lose any events and leave the system inconsistent.
How to atomically update the store and send the event?
One approach could be the usage of the outbox pattern:
● Create a database table for the events.
● Atomically update the internal microservice database and insert a record into
the table for the events.
The Change Data Capture Component (Connector) reads the table for the events and
publish the events to the message broker.
https://github.com/debezium/debezium-examples/tree/master/outbox
transactional
ticket table ticket events table
ticket events topic
Change Data
Ticket Service update ticket state Capture
Saga Choreography
We don’t want to lose any events and leave the system inconsistent.
How to atomically update the store and send the event?
Other approaches:
● Database transaction log mining: a process extracts the database updates using
the database transaction log and publish them to the message broker.
Saga Choreography
Services must discard duplicate events.
A message log table can be used to track all events already processed.
The correlation-id (event-id) can be used to find the event into message log table.
Saga Choreography
Let’s imagine that we don’t receive a PAYMENT_ACCEPTED or
PAYMENT_REFUSED event.
The lack of a Saga Coordinator is the real limit of the Saga Choreography
approach.
Saga Choreography
a custom solution with Quarkus, Debezium and Kafka
https://github.com/redhat-italy/rht-summit2019-saga
Why Quarkus?
Supersonic Subatomic Java
The new era of Java application, a 100% cloud native stack
Super fast boot time, low RSS memory (not only java heap)
debezium-kafka-connect
Insurance
ticket topic Insurance Connector Service
Postgres
insurance event table insurance table
quarkus
eclipse-microprofile
debezium-kafka-connect
Payment
Postgres payment topic
Payment Connector Service
ticket table ticket event table
Postgres
payment event table payment table
ElasticSearch +Kibana
DEMO
Saga - Choreography
Saga Orchestration
Saga is a series of local transactions; every local transaction happens within the
boundary of the (micro)-service.
This coordinator service is responsible for centralizing the saga’s decision making and
sequencing business logic.
It will be part of the Microprofile specification: the reaction to the slow pace of Java EE
development.
What is Eclipse MicroProfile?
MicroProfile 2.2
= New
= Updated
= No change from last release (MicroProfile 2.1)
Eclipse MicroProfile 3.0 (June 2019)
Outside
Open Rest Client Reactive
Open API 1.1 Config 1.3
Tracing 1.3 1.2 Streams
Operators 1.1
Fault JWT
Health
Tolerance Metrics 2.0 Propagation
Check 2.0 GraphQL 1.0
2.0 1.1
Guarantees shared state is protected from conflicting updates from multiple users.
Removes the Isolation (locking) ACID property. It uses the BASE (Basically Available,
Soft state, Eventual consistency) approach.
Eventual Consistency where each resource will move from a valid state to another.
Saga Orchestration Model
TRANSACTION MANAGER
LRA COORDINATOR
Business Flow
Saga Orchestration - Complete Phase
Book
Initial Book
Ticket Payment
State Ticket
Insurance
Joins SAGA
Joins SAGA Joins SAGA
TRANSACTION MANAGER
LRA COORDINATOR
Send
Complete to
@Complete @Complete
coordinator
Confirm
Final Confirm
Book Ticket
State Book Ticket
Insurance
Saga Orchestration - Compensation Phase
Book
Initial Book
Ticket Payment
State Ticket
Insurance
Joins SAGA
Joins SAGA Joins SAGA
TRANSACTION MANAGER
LRA COORDINATOR
Send
Compensate
@Compensate @Compensate
to coordinator
Cancel
Final Cancel
Book Ticket
State Book Ticket
Insurance
Saga Orchestration
with Narayana
3 microservices with rest endpoints
https://github.com/redhat-italy/rht-summit2019-saga
Eclipse MicroProfile Community
DEMO
Saga - Orchestration
Saga Orchestration
with Apache Camel
● API Gateway: a sample camel app that is the main entry point
● Flight Service: a service that sells flights
● Train Service: a service that sells train tickets
● Payment Service: a service that allows both services to request
payments
● Narayana LRA coordinator
https://github.com/nicolaferraro/camel-saga-quick
start
Saga as state machines
Saga is essentially a state machine.
A BPMN process can represents well the workflow behind a Saga flow.
● The process implements the Saga pattern via standard BPMN2 compensation
flows, showing the powerful concepts and ease of semantical expression that
Red Hat Process Automation Manager 7 brings to a modern microservices
architecture.
● The order in the order service is cancelled via a BPMN2 compensation flow
when the order time’s out.
https://github.com/jbossdemocentral/rhpam7-order-it-hw-demo
Credits
Ugo Landini - Principal Solutions Architect @ Red Hat
Fabio Massimo Ercoli - Senior Software Engineer - Hibernate & Data Platform @ Red Hat
WEDNESDAY
10:15-11:00 AM - 11:15-12:00 PM - How 12:15-1:00 PM - Container
Day-in-the-Life: Designing Volkswagen used microservices adoption at scale:
Software for Open & automation to develop Metrics-driven framework and
Innovation Labs self-service solutions other lessons learned
3:15-4:00 PM - The road to 4:15-5:00 PM - Adoptando 5:15-6:00 PM - A DevOps 6:15-7 PM - Digital Nudge:
RHEL 8: Best practices for RHEL 8: Las mejores survival guide: Small How automation, machine
optimizing your operating practicas para optimizar tu changes lead to big results learning, A.I., and more
system Sistema Operativo shape our digital decisions
THURSDAY
10:45-11:30 AM - OpenShift 11:45-12:30 PM - To the 12:45-1:30 PM - People first, digital 1:45-2:30 PM - Monoliths in
DevSecOps: Making your Edge and Beyond: Network second: Using open principles to OpenShift: Application
enterprise more secure for Automation for drive transformation at Heritage onboarding strategies for
tomorrow, today Telecommunications Bank containers