4 ms·
IMO Ecto.Multi is an anti-pattern. It's just an internal DSL using builder pattern to create a pipeline running inside a client-side Ecto transaction. Transac
by nivertech 6y ago
IMO Ecto.Multi is an anti-pattern.
It's just an internal DSL using builder pattern to create a pipeline running inside a client-side Ecto transaction.
Transactions should be avoided (especially the client-side ones), and in cases when they're absolutely needed - their run time should be reduced to a minimum, i.e. avoid long-running code inside a transaction in order not to block other processes using the same DB connection.
Some examples of non-DB related code usually called from inside client-side transaction:
- input validations / preconditions checks
- side-effects: sending emails / push notifications / etc.
- communicating with 3rd party services
The solution for this isn't easy, usually involves application-specific knowledge, or using Saga pattern.
Ecto.Multi can be easily replaced by using "with" statement inside an Ecto transaction, as described in [1].
Unlike Ecto.Multi where each step has a label, when using "with" statement you don't know on which step the transaction failed. The solution is to use "tagged with statement" pattern like shown in [2].
The only advantages of Ecto.Multi are:
- dynamically-built transactions
- testability (but these tests are questionable anyway, after all you're not testing regular Elixir pipelines)
--
[1] https://medium.com/very-big-things/towards-maintainable-elixir-the-anatomy-of-a-core-module-b7372009ca6d#142c https://medium.com/very-big-things/towards-maintainable-elix...
[2] https://dev.to/aloukissas/elixir-s-with-statement-is-fantastic-3f2g https://dev.to/aloukissas/elixir-s-with-statement-is-fantast...