MID-02 - Implement transactional middleware #1
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
This PR is a potential implementation of transactional middleware.
Today, all
EctoMiddleware
behaviours are assumed to not be transactional, which might be fine for certain use-cases, but not for others.For example, if one wanted to create an event log by hooking into all CRUD operations today, there is a very real risk that it would not be a sound implementation because writing to the events log would not be atomic with the CRUD operation.
This PR introduces a new optional callback to the
EctoMiddleware
behaviour:transactional?/0
, which, if implemented and set totrue
, will:Ecto.Repo
callback (such asget_by/2
) in a transactionget_by/2
implementationIf no configured
EctoMiddleware
are marked astransactional?
then we avoid starting a transaction as this may be quite expensive.In reality, it's hard to foresee a usecase where an
EctoMiddleware
implementation would always want to run inside a transaction... this would certainly tank performance.Due to this,
EctoMiddleware
now exports aset_transactional/2
function which can be used to toggle middleware to be transactional on a middleware by middleware, process by process basis.Note that if you have a mix of middleware configured which are transactional and non-transactional, the execution order of the middleware is as follows:
before_middleware
which are not transactionalbefore_transactional_middleware
if these existEcto.Repo
callbackafter_transactional_middleware
if these existafter_middleware
which are not transactionalBefore merging this PR in, we should really also implement a test suite.
Additional changes to EctoHooks which is the driver for this change will be implemented in tandem with this change.