SlideShare a Scribd company logo
@crichardson
Events and commands: developing
asynchronous microservices
Chris Richardson
Founder of Eventuate.io
Founder of the original CloudFoundry.com
Author of POJOs in Action and Microservices Patterns
@crichardson
chris@chrisrichardson.net
http://learn.microservices.io
Copyright © 2018. Chris Richardson Consulting, Inc. All rights reserved
@crichardson
Presentation goal
Using asynchronous
messaging to implement
transactions and queries in a
microservice architecture
@crichardson
About Chris
@crichardson
About Chris
Consultant and trainer
focussed on helping
organizations adopt the
microservice architecture
(http://www.chrisrichardson.net/)
@crichardson
About Chris
Founder of a startup that is creating
an open-source/SaaS platform
that simplifies the development of
transactional microservices
(http://eventuate.io)
@crichardson
About Chris
https://www.manning.com/books/microservices-patterns
40% discount with code
cwtcodeone18
About Chris: microservices.io
Microservices pattern
language
Articles
Code examples
Microservices Assessment
Platform - coming soon
@crichardson
Agenda
Transactions, queries and microservices
Managing transactions with sagas
Implementing queries with CQRS
The microservice architecture
structures
an application as a
set of loosely coupled
services
@crichardson
API
Service = independently deployable
component
Operations
Event
Publisher
Commands
Queries
Synchronous
REST/gRPC
Asynchronous
Messaging
Events
Event
Subscriber
API
Client
Invokes
Operations
Events
Service
Database
@crichardson
Microservices enable
continuous delivery/deployment
Process:
Continuous delivery/deployment
Organization:
Small, agile, autonomous,
cross functional teams
Architecture:
Microservice architecture
Enables
Enables
Enables
Successful
Software
Development
Services
=
testability
and
deployability
Teams own services
@crichardson
Let’s imagine that you are
building an online store API
createCustomer(creditLimit)
createOrder(customerId, orderTotal)
findOrdersForCustomer(customerId)
findRecentCustomers()
Order
Management
Customer
Management
REST API
…
@crichardson
Order
Service
createCustomer()
createOrder()
findOrdersForCustomer()
findRecentCustomers()
API Gateway
createCustomer()
createOrder()
Order DatabaseCustomer Database
Order tableCustomer table
REST API
REST API
Essential for loose
coupling
Must reserve
customer’s credit
Retrieve data
from both
services
Customer
Service
REST API
availableCredit
….
OrderTotal
….
@crichardson
No ACID transactions that span
services
BEGIN TRANSACTION
…
SELECT ORDER_TOTAL
FROM ORDERS WHERE CUSTOMER_ID = ?
…
SELECT CREDIT_LIMIT
FROM CUSTOMERS WHERE CUSTOMER_ID = ?
…
INSERT INTO ORDERS …
…
COMMIT TRANSACTION
Private to the
Order Service
Private to the
Customer Service
Distributed transactions
@crichardson
Querying across services is
not straightforward
SELECT *
FROM CUSTOMER c, ORDER o
WHERE
c.id = o.ID
AND c.id = ?
Private to Customer
Service
Private to Order
Service
Find customer and their orders
@crichardson
Agenda
Transactions, queries and microservices
Managing transactions with sagas
Implementing queries with CQRS
@crichardson
From a 1987 paper
@crichardson
Saga
Use Sagas instead of 2PC
Distributed transaction
Service A Service B
Service A
Local
transaction
Service B
Local
transaction
Service C
Local
transaction
X Service C
https://microservices.io/patterns/data/saga.html
@crichardson
Order Service
Create Order Saga
Local transaction
Order
state=PENDING
createOrder()
Customer Service
Local transaction
Customer
reserveCredit()
Order Service
Local transaction
Order
state=APPROVED
approve
order()
createOrder() Initiates saga
@crichardson
Saga design challenges
API design
Synchronous REST API initiates asynchronous saga
When to send back a response?
Rollback compensating transactions
Sagas are ACD - No I
Sagas are interleaved anomalies, such as lost updates
Must use countermeasures
https://www.slideshare.net/chris.e.richardson/saturn-2018-managing-data-consistency-in-a-microservice-architecture-using-sagas
How do the saga participants
communicate?
Synchronous
communication, e.g. REST
= temporal coupling
Client and server need to
be both available
Customer Service fails
retry provided it’s
idempotent
Order Service fails Oops
Order
Service
createOrder()
REST
Customer
Service
reserveCredit()
REST
@crichardson
Collaboration using asynchronous,
broker-based messaging
Order Service
Customer
Service
….
Message broker
At least once delivery ensures a saga completes when
its participants are temporarily unavailable
@crichardson
Saga step = a transaction
local to a service
Service
Database Message Broker
update publish message/event
How to
make atomic
without 2PC?
@crichardson
How to sequence the saga
transactions?
After the completion of transaction Ti “something” must
decide what step to execute next
Success: which T(i+1) - branching
Failure: C(i - 1)
@crichardson
Choreography: distributed decision making
vs.
Orchestration: centralized decision making
@crichardson
Agenda
Overview
Choreography
Orchestration
Transactional
messaging
Transactions, queries and microservices
Managing transactions with sagas
Implementing queries with CQRS
@crichardson
Choreography-based coordination
using events
Order cancelled
Order
Service
Customer
Service
DB DB
Order created
Domain event
Subscriber
updates its DB
Abstracts
message broker
Message channel
@crichardson
Message broker
Choreography-based Create Order
Saga
Order created
Credit Reserved
Credit Limit Exceeded
Create Order
OR
Customer
creditLimit
creditReservations
Order
state
total
create()
reserveCredit()
approve()/
reject()
Order events channel
Customer events channel
Order
Service
Customer
Service
@crichardson
API
Order Service
Operations
createOrder()
Event
Publisher
Order
events
Event
Subscriber
Customer
Events
Service
Database
@crichardson
API
Customer Service
Operations
createCustomer()
Event
Publisher
Customer
Events
Event
Subscriber
Order
Events
Service
Database
Benefits and drawbacks of
choreography
Benefits
Simple, especially when using
event sourcing
Participants are loosely coupled
Drawbacks
Cyclic dependencies - services
listen to each other’s events,
e.g. Customer Service must
know about all Order events
that affect credit
Overloads domain objects, e.g.
Order and Customer know too
much
Events = indirect way to make
something happen
https://github.com/eventuate-examples/eventuate-examples-java-customers-and-orders
@crichardson
Overview
Choreography
Orchestration
Transactional
messaging
Agenda
Transactions, queries and microservices
Managing transactions with sagas
Implementing queries with CQRS
@crichardson
Order Service
Orchestration-based coordination using
command messages
Local transaction
Order
state=PENDING
createOrder()
Customer Service
Local transaction
Customer
reserveCredit()
Order Service
Local transaction
Order
state=APPROVED
approve
order()
createOrder() CreateOrderSaga
InvokesInvokesInvokes
@crichardson
Request/asynchronous reply-
based communication
Release credit
Order
Service
Customer
Service
DB
DB
Reserve credit
Command
Customer service
command channel
Create Order saga
Reply channel
Reply
Orchestrator
Update Credit
@crichardson
A saga (orchestrator)
is a persistent object
that
tracks the state of the saga
and
invokes the participants
Saga orchestrator behavior
On create:
Invokes a saga participant
Persists state in database
Wait for a reply
On reply:
Load state from database
Determine which saga
participant to invoke next
Invokes saga participant
Updates its state
Persists updated state
Wait for a reply
…
@crichardson
Order Service
CreateOrderSaga orchestrator
Customer Service
Create Order
Customer
creditLimit
creditReservations
...
Order
state
total…
reserveCredit()
CreateOrder
Saga
OrderService
create()
create()
approve()
Credit Reserved
Customer command channel
Saga reply channel
@crichardson
API
Order Service
Operations
createOrder()
API
Client
Invokes
Customer
Service
Service
Database
reserveCredit()
releaseCredit()
@crichardson
API
Customer Service
Operations
createCustomer()
reserveCredit()
releaseCredit()
Service
Database
Simple
API
@crichardson
Eventuate Tram Sagas
Open-source Saga orchestration framework
Currently for Java
https://github.com/eventuate-tram/eventuate-tram-sagas
https://github.com/eventuate-tram/eventuate-tram-sagas-
examples-customers-and-orders
Benefits and drawbacks of
orchestration
Benefits
Centralized coordination
logic is easier to understand
Reduced coupling, e.g.
Customer Service knows
less. Simply has API for
managing available credit.
Reduces cyclic
dependencies
Drawbacks
Risk of smart sagas
directing dumb services
@crichardson
Overview
Choreography
Orchestration
Transactional
messaging
Agenda
Transactions, queries and microservices
Managing transactions with sagas
Implementing queries with CQRS
@crichardson
Messaging must be
transactional
Service
Database Message Broker
update publish
How to
make atomic
without 2PC?
@crichardson
Option: Event sourcing
=
Event centric approach to
business logic and persistence
http://eventuate.io/
@crichardson
Event sourcing: persists an object
as a sequence of events
Event table
Entity type
Event
id
Entity
id
Event
data
Order 902101 …OrderApproved
Order 903101 …OrderShipped
Event
type
Order 901101 …OrderCreated
Order
create()
approve()
ship()
Event Store
@crichardson
Replay events to recreate in memory state
Order
state
apply(event)
Event table
Entity type
Event
id
Entity
id
Event
data
Order 902101 …OrderApproved
Order 903101 …OrderShipped
Event
type
Order 901101 …OrderCreated
Event Store
Load events by ID and call apply()
Instantiate with
default
constructor
Event store =
database
@crichardson
Event sourcing guarantees: state
change -> event is published
Event table
Entity type
Event
id
Entity
id
Event
data
Order 902101 …OrderApproved
Order 903101 …OrderShipped
Event
type
Order 901101 …OrderCreated
Event Store
Customer
Service
Subscribe
Event store =
message broker
@crichardson
Preserves history of domain objects
Supports temporal queries
Built-in auditing
Other benefits of event sourcing
@crichardson
Evolving the schema of long-lived
events
Event store only supports PK-
based access, requires CQRS
Drawbacks of event sourcing
@crichardson
Option:
Traditional persistence
(JPA, MyBatis,…)
+
Business logic calls event
publishing API
https://github.com/eventuate-tram/eventuate-tram-core
@crichardson
Spring Data for JPA example
Publish event
Save order
http://eventuate.io/exampleapps.html
@crichardson
Atomically updating state and
publishing events
ACID
transaction
See BASE: An Acid Alternative, http://bit.ly/ebaybase
DELETE
?
Customer
Service
ORDER_ID CUSTOMER_ID TOTAL
99
CUSTOMER_CREDIT_RESERVATIONS table
101 1234
ID TYPE DATA DESTINATION
MESSAGE table
84784 CreditReserved {…} …
INSERT INSERT
Message
Publisher
QUERY
Message
Broker
Publish
Local transaction
reserveCredit()
@crichardson
Publishing messages inserted
into MESSAGE table
Poll the MESSAGE table
Simple
But what about latency?
Use Transaction log tailing
a.k.a. change data capture
Lower latency
But implementation is database specific!
MESSAGE
Table
Message
Publisher
Message
Brokerhttp://eventuate.io/exampleapps.html
@crichardson
Agenda
Transactions, queries and microservices
Managing transactions with sagas
Implementing queries with CQRS
@crichardson
Queries often retrieve data
owned by multiple services
@crichardson
API Composition pattern
Customer Service
Customer
…
Order Service
Order
…
API Gateway
findOrdersForCustomer(customerId)
GET /customer/id GET /orders?customerId=id
FK query!
https://microservices.io/patterns/data/api-composition.html
@crichardson
Find recent, valuable
customers
SELECT *
FROM CUSTOMER c, ORDER o
WHERE
c.id = o.ID
AND o.ORDER_TOTAL > 100000
AND o.STATE = 'SHIPPED'
AND c.CREATION_DATE > ?
Customer
Service
Order Service
…. is even more difficult!
API Composition would be
inefficient
1 + N strategy:
Fetch recent customers
Iterate through customers
fetching their shipped
orders
Lots of round trips
high-latency
Alternative strategy:
Fetch recent customers
Fetch recent orders
Join
2 roundtrips but
potentially large datasets
inefficient
@crichardson
Using events to update a queryable
replica = CQRS
Order
Service
Customer
Service
Order events
Customer events
findCustomersAndOrders()
Order events channel
Customer events channel
Customer
Order
View
Service
Replica
View
Database
https://microservices.io/patterns/data/cqrs.html
@crichardson
Query side data model
Command Query Responsibility
Segregation (CQRS)
Command side data model
Commands
Aggregate
Message broker or Event Store
Events
Queries
(Materialized)
View
Events
POST
PUT
DELETE
GET
@crichardson
Queries database (type)
Command side
POST
PUT
DELETE
Aggregate
Event Store/Message Broker
Events
Query side
GET /customers/id
MongoDB
Query side
GET /orders?text=xyz
ElasticSearch
Query side
GET …
Neo4j
@crichardson
A CQRS view can be part of a
service
Restaurant
Service
Restaurant events channel
Transactional
Source of truth
CQRS replica for
geo/text search
createRestaurant()
…
findRestaurantsNear(location, keywords)
MySQL
Elastic

Search
@crichardson
Use a CQRS replica to validate
commands
Order Service
createOrder()
Customer
Service
Orders
Customers
creditLimit
availableCredit
Customer events
Replica
Checks available credit
without invoking Customer
Service
@crichardson
Summary
Use synchronous protocols, e.g. REST or gRPC:
External APIs
(Read only) API Composition
Use asynchronous messaging to solve distributed data management problems
Services publish events to implement
choreography-based sagas
queries using CQRS views
Services publish events using either event sourcing or explicit publishing
Services send command messages to implement orchestration-based sagas
@crichardson
@crichardson chris@chrisrichardson.net
http://learn.microservices.io
Questions?
40% discount with code
cwtcodeone18

More Related Content

PDF
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
PDF
OReilly SACON2018 - Events on the outside, on the inside, and at the core
PDF
YOW! Perth: Cubes, Hexagons, Triangles, and More: Understanding the Microserv...
PDF
Designing loosely coupled services
PDF
Oracle CodeOne 2019: Decompose Your Monolith: Strategies for Migrating to Mic...
PDF
SVCC Developing Asynchronous, Message-Driven Microservices
PDF
Gluecon: Using sagas to maintain data consistency in a microservice architecture
PDF
Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strate...
QConPlus 2021: Minimizing Design Time Coupling in a Microservice Architecture
OReilly SACON2018 - Events on the outside, on the inside, and at the core
YOW! Perth: Cubes, Hexagons, Triangles, and More: Understanding the Microserv...
Designing loosely coupled services
Oracle CodeOne 2019: Decompose Your Monolith: Strategies for Migrating to Mic...
SVCC Developing Asynchronous, Message-Driven Microservices
Gluecon: Using sagas to maintain data consistency in a microservice architecture
Oracle CodeOne 2019: Descending the Testing Pyramid: Effective Testing Strate...

What's hot (20)

PDF
GotoChgo 2019: Not Just Events: Developing Asynchronous Microservices
PDF
There is no such thing as a microservice! (oracle code nyc)
PDF
YOW2018 - Events and Commands: Developing Asynchronous Microservices
PDF
MicroCPH - Managing data consistency in a microservice architecture using Sagas
PDF
Mucon: Not Just Events: Developing Asynchronous Microservices
PDF
Decompose your monolith: strategies for migrating to microservices (Tide)
PDF
Omnikron webbinar - Microservices: enabling the rapid, frequent, and reliable...
PDF
QCONSF - ACID Is So Yesterday: Maintaining Data Consistency with Sagas
PDF
Events to the rescue: solving distributed data problems in a microservice arc...
PDF
JFokus: Cubes, Hexagons, Triangles, and More: Understanding Microservices
PDF
microXchg: Managing data consistency in a microservice architecture using Sagas
PDF
Kong Summit 2018 - Microservices: decomposing applications for testability an...
PDF
Saturn2017: No such thing as a microservice!
PDF
Spring Days NYC - A pattern language for microservices
PDF
Decompose your monolith: Six principles for refactoring a monolith to microse...
PDF
An overview of the Eventuate Platform
PDF
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
PDF
ArchSummit Shenzhen - Using sagas to maintain data consistency in a microserv...
PDF
Solving distributed data management problems in a microservice architecture (...
PDF
#JaxLondon keynote: Developing applications with a microservice architecture
GotoChgo 2019: Not Just Events: Developing Asynchronous Microservices
There is no such thing as a microservice! (oracle code nyc)
YOW2018 - Events and Commands: Developing Asynchronous Microservices
MicroCPH - Managing data consistency in a microservice architecture using Sagas
Mucon: Not Just Events: Developing Asynchronous Microservices
Decompose your monolith: strategies for migrating to microservices (Tide)
Omnikron webbinar - Microservices: enabling the rapid, frequent, and reliable...
QCONSF - ACID Is So Yesterday: Maintaining Data Consistency with Sagas
Events to the rescue: solving distributed data problems in a microservice arc...
JFokus: Cubes, Hexagons, Triangles, and More: Understanding Microservices
microXchg: Managing data consistency in a microservice architecture using Sagas
Kong Summit 2018 - Microservices: decomposing applications for testability an...
Saturn2017: No such thing as a microservice!
Spring Days NYC - A pattern language for microservices
Decompose your monolith: Six principles for refactoring a monolith to microse...
An overview of the Eventuate Platform
DDD SoCal: Decompose your monolith: Ten principles for refactoring a monolith...
ArchSummit Shenzhen - Using sagas to maintain data consistency in a microserv...
Solving distributed data management problems in a microservice architecture (...
#JaxLondon keynote: Developing applications with a microservice architecture
Ad

Similar to Oracle Code One: Events and commands: developing asynchronous microservices (20)

PDF
JavaOne2017: ACID Is So Yesterday: Maintaining Data Consistency with Sagas
PDF
Saturn 2018: Managing data consistency in a microservice architecture using S...
PDF
Saga transactions msa_ architecture
PPTX
Saga about distributed business transactions in microservices world
PDF
Overview of the Eventuate Tram Customers and Orders application
PPTX
Event Driven Microservices architecture
PDF
Melbourne Jan 2019 - Microservices adoption anti-patterns: Obstacles to decom...
PDF
JS Fest 2019/Autumn. Anton Cherednikov. Choreographic or orchestral architect...
PDF
Microservice
PDF
Komunikacja oparta o eventy w architekturze mikroserwisowej
PDF
Microservices pattern language (microxchg microxchg2016)
PDF
A pattern language for microservices
PDF
MuleSoft Nashik Virtual Meetup#2 - API Led Connectivity Integration:SAGA
PDF
Decompose that WAR? A pattern language for microservices (@QCON @QCONSP)
PPTX
Microservices Architecture Part 2 Event Sourcing and Saga
PDF
2019 03-13-implementing microservices by ddd
PDF
A pattern language for microservices - Chris Richardson
PPTX
Event Driven Architecture
PDF
Events and microservices
PDF
A pattern language for microservices - June 2021
JavaOne2017: ACID Is So Yesterday: Maintaining Data Consistency with Sagas
Saturn 2018: Managing data consistency in a microservice architecture using S...
Saga transactions msa_ architecture
Saga about distributed business transactions in microservices world
Overview of the Eventuate Tram Customers and Orders application
Event Driven Microservices architecture
Melbourne Jan 2019 - Microservices adoption anti-patterns: Obstacles to decom...
JS Fest 2019/Autumn. Anton Cherednikov. Choreographic or orchestral architect...
Microservice
Komunikacja oparta o eventy w architekturze mikroserwisowej
Microservices pattern language (microxchg microxchg2016)
A pattern language for microservices
MuleSoft Nashik Virtual Meetup#2 - API Led Connectivity Integration:SAGA
Decompose that WAR? A pattern language for microservices (@QCON @QCONSP)
Microservices Architecture Part 2 Event Sourcing and Saga
2019 03-13-implementing microservices by ddd
A pattern language for microservices - Chris Richardson
Event Driven Architecture
Events and microservices
A pattern language for microservices - June 2021
Ad

More from Chris Richardson (12)

PDF
The microservice architecture: what, why, when and how?
PDF
More the merrier: a microservices anti-pattern
PDF
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
PDF
Dark Energy, Dark Matter and the Microservices Patterns?!
PDF
Dark energy, dark matter and microservice architecture collaboration patterns
PDF
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
PDF
Using patterns and pattern languages to make better architectural decisions
PDF
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
PDF
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
PDF
Microservices - an architecture that enables DevOps (T Systems DevOps day)
PDF
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
PDF
#DevNexus202 Decompose your monolith
The microservice architecture: what, why, when and how?
More the merrier: a microservices anti-pattern
YOW London - Considering Migrating a Monolith to Microservices? A Dark Energy...
Dark Energy, Dark Matter and the Microservices Patterns?!
Dark energy, dark matter and microservice architecture collaboration patterns
Scenarios_and_Architecture_SkillsMatter_April_2022.pdf
Using patterns and pattern languages to make better architectural decisions
iSAQB gathering 2021 keynote - Architectural patterns for rapid, reliable, fr...
Mucon 2021 - Dark energy, dark matter: imperfect metaphors for designing micr...
Microservices - an architecture that enables DevOps (T Systems DevOps day)
TDC2020 - The microservice architecture: enabling rapid, reliable, frequent a...
#DevNexus202 Decompose your monolith

Recently uploaded (20)

PDF
Wondershare Filmora 15 Crack With Activation Key [2025
PDF
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
PDF
Understanding Forklifts - TECH EHS Solution
PDF
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
PDF
2025 Textile ERP Trends: SAP, Odoo & Oracle
PPTX
Operating system designcfffgfgggggggvggggggggg
PDF
System and Network Administration Chapter 2
PDF
Which alternative to Crystal Reports is best for small or large businesses.pdf
PPTX
Online Work Permit System for Fast Permit Processing
PDF
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
PDF
AI in Product Development-omnex systems
PDF
Odoo Companies in India – Driving Business Transformation.pdf
PDF
Softaken Excel to vCard Converter Software.pdf
PDF
How Creative Agencies Leverage Project Management Software.pdf
PPTX
CHAPTER 2 - PM Management and IT Context
PPTX
history of c programming in notes for students .pptx
PDF
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
PPTX
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
PDF
How to Migrate SBCGlobal Email to Yahoo Easily
PPTX
Odoo POS Development Services by CandidRoot Solutions
Wondershare Filmora 15 Crack With Activation Key [2025
Flood Susceptibility Mapping Using Image-Based 2D-CNN Deep Learnin. Overview ...
Understanding Forklifts - TECH EHS Solution
SAP S4 Hana Brochure 3 (PTS SYSTEMS AND SOLUTIONS)
2025 Textile ERP Trends: SAP, Odoo & Oracle
Operating system designcfffgfgggggggvggggggggg
System and Network Administration Chapter 2
Which alternative to Crystal Reports is best for small or large businesses.pdf
Online Work Permit System for Fast Permit Processing
Why TechBuilder is the Future of Pickup and Delivery App Development (1).pdf
AI in Product Development-omnex systems
Odoo Companies in India – Driving Business Transformation.pdf
Softaken Excel to vCard Converter Software.pdf
How Creative Agencies Leverage Project Management Software.pdf
CHAPTER 2 - PM Management and IT Context
history of c programming in notes for students .pptx
T3DD25 TYPO3 Content Blocks - Deep Dive by André Kraus
Agentic AI Use Case- Contract Lifecycle Management (CLM).pptx
How to Migrate SBCGlobal Email to Yahoo Easily
Odoo POS Development Services by CandidRoot Solutions

Oracle Code One: Events and commands: developing asynchronous microservices