Last week we showed you Elixir from a Rubyist’s Perspective. Today we’re going back to a technical path and will share with you a new tool we recently found. If you use Elixir you might wonder about how to handle distributed transactions. To run them you can use Sagas pattern. And Sage is a Sagas pattern implementation in Elixir!
Here’s an intro. Saga is a very simple failure management pattern that originates from 1987’s paper on long-running transactions for databases. Its use case was implementing long-lived transactions without locking the database. Those transactions can take a while because they should go through a large dataset and make the system unavailable due to various locks that need to be placed, which is usually not desirable.
In a nutshell, Saga is a distributed transaction which takes care of overall consistency of collection of steps that internally perform atomic transactions. Those steps consist of subtransaction and compensation to amend its effects.
And Sage is a dependency-free pure Elixir library inspired by Sagas pattern. It provides set of additional features on top of steps, transactions, and compensations defined by the original paper.
Sage is particularly useful when dealing with:
- Microservices (maybe not the best case because you have control over them and there are much more options to consider).
- Data which is split between multiple databases or partitions, which is somewhat similar to microservices.
- When communicating with external services (because here we interact with a system which is out of our control, has limited set of features exposed over API and unlikely to change on our demand).
Sage can help to elegantly organize logic in your domain contexts.
What is coming out of the box with Sage?
- Transaction retries;
- Asynchronous transactions with timeout;
- Retries with exponential backoff and jitter;
- Ease to write circuit breakers;
- Code that is clean and easy to test;
- Low cost of integration in existing code base and low-performance overhead;
- Ability to not lock the database with long running transactions;
- Extensibility – write your own handler for critical errors or metric collector to measure how much time each step took.
Read about what is Saga in details, asynchronous transactions in Sage, error handling, things to come and the rest of interesting and important details in Andrew Dryga’s article!
Also, feel free to add a star on GitHub.