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 comment
[ 4.1 ms ] story [ 15.6 ms ] threadIt'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-elix...
[2] https://dev.to/aloukissas/elixir-s-with-statement-is-fantast...