📰 Read operations
Load Reduce State
A little bit expensive for read operations…
… and not really great for querying :(
Slide 15
Slide 15 text
📽 Projections
Using subscribe to build a queryable representation of the
application state (aka Projections)
Subscribe Projections
Projector
ℹ A good database for event sourcing must have a data streaming mechanism
Slide 16
Slide 16 text
✋ Keep that in mind
App DB Projections
Append Subscribe
App
Projections
Append
Publish
✅
❌
DB
❗ Even if you’re using a Message Broker or an Event Bus
Slide 17
Slide 17 text
⚠ Eventually consistent
CAP Theorem (Eric Brewer)
Consistency
Availability
Partition tolerance
All system nodes needs to manipulate
exactly the same data at the same time
Requests must succeed
Node failure must not create a complete
system failure
A distributed system can only guarantee 2 constraints at the same time, not 3…
Slide 18
Slide 18 text
🔃 CQRS pattern
What is CQRS?
• A pattern designed by Greg Young
• Command Query Responsibility Segregation
• Read != Write (different needs)
Query
A read operation
Command
Validation
Business logic
Persistence
CQRS suit perfectly well with Event Sourcing!
Slide 19
Slide 19 text
🔃 CQRS pattern
GetBalance
Query
Deposite
Command
GetAllOperation
Query
Withdraw
Command
… …
Dispatcher
Read
DB
Dispatcher
QueryHandler CommandHandler
Event
Store
Projection Projection
Aggregate
State
Events Behaviors
Slide 20
Slide 20 text
☁ Azure
Flexibility Hyper scale Out of the box
Slide 21
Slide 21 text
🗃 PostgreSQL - Table
CREATE TABLE "EVENT_STREAM" (
"streamId" VARCHAR NOT NULL,
"createdAt" VARCHAR NOT NULL,
"type" VARCHAR NOT NULL,
"version" INTEGER NOT NULL,
"payload" JSONB,
PRIMARY KEY ("streamId", "createdAt", "version")
);
CREATE INDEX ON "EVENT_STREAM" ("streamId");
Slide 22
Slide 22 text
🗃 PostgreSQL - Notify
CREATE FUNCTION notify_new_event() RETURNS TRIGGER AS
$trigger$
BEGIN
PERFORM pg_notify('new_event', row_to_json(NEW)::text);
RETURN NULL;
END;
$trigger$
LANGUAGE plpgsql VOLATILE
COST 100;
Slide 23
Slide 23 text
🗃 PostgreSQL - Trigger
CREATE TRIGGER notify_new_event
AFTER INSERT
ON "EVENT_STREAM"
FOR EACH ROW
EXECUTE PROCEDURE notify_new_event();
Slide 24
Slide 24 text
🗃 PostgreSQL - Rules
CREATE FUNCTION THROW_WHEN_TYRING_TO_UPDATE_EVENT_STREAM()
RETURNS VOID AS
$$
BEGIN
RAISE EXCEPTION 'Event Stream can not be updated';
END;
$$ LANGUAGE plpgsql VOLATILE;
CREATE RULE "PREVENT_DELETE_ON_EVENT_STREAM" AS
ON DELETE TO "EVENT_STREAM" DO INSTEAD
SELECT THROW_WHEN_TYRING_TO_UPDATE_EVENT_STREAM();
CREATE RULE "PREVENT_UPDATE_ON_EVENT_STREAM" AS
ON UPDATE TO "EVENT_STREAM" DO INSTEAD
SELECT THROW_WHEN_TYRING_TO_UPDATE_EVENT_STREAM();
Slide 25
Slide 25 text
🗃 PostgreSQL - Load events
SELECT
"type",
"payload",
"version"
FROM "EVENT_STREAM"
WHERE "streamId" = $1 ORDER BY "createdAt", "version"
🗃 PostgreSQL - Conclusion
✅ ❌
• Simple to implement
• One impl for all languages
• On premise if needed
• DB Tuning
• You must know how to do it
• Distributed
• No acknowledgement
Slide 28
Slide 28 text
🗃 SQL Server
The same thing but with “Service Broker” 😅
Slide 29
Slide 29 text
🌐 Cosmos DB
Change feed for the win!
Change Feed
Event
Stream
Data
Slide 30
Slide 30 text
🌐 Cosmos DB
Table, Trigger, Notify ➡ Nothing to do !!!
🌀 Event Store DB
✅
• Out of the box
• State of the art
• Built in projection
• On premise if needed
• Manage outside of Azure…
• Not too much customization
• Only gRPC client
❌