alchimia
alchimia copied to clipboard
Async context manager for transactions
Current coverage is 98.15% (diff: 100%)
No coverage report found for master at 699f2e8.
Powered by Codecov. Last update 699f2e8...8b73d16
I love the idea for the feature, and the docs are great.
However, I don't love using an async context manager for this. For some simple cases, it might be good to have a context manager, but there are a number of reasons to avoid it:
- There's the obvious point that it only works in 3.5+. Still a lot of legacy code that won't be usable with this for years to come; transactions are not a "fancy" or optional feature. You need them for any even halfway-functioning SQL application.
- It's an abstraction inversion. There should be a nice transaction object which can be started and finished with just regular ol' methods before we get into a specific convenience layer (in large part because if this
async with
convenience layer is a good idea, it should still be implemented in a way where the underlying logic is usable in <3.5). - It's a limiting design, because it highlights one of the weaknesses of context managers generally: the only-execute-once nature of their specification. In more sophisticated / concurrent database applications, transactions which create conflicts should be automatically retried. This means the transaction needs to be a callable, that can be called multiple times. Context managers have no API for re-entering, and it would be awkward in the extreme to require everyone who wants correct, retry-on-conflict transactions to do something like
async with Transaction(...) as blub: while blub.transaction_should_keep_going: try: ... except RetriableTransactionException: pass
For reference, the hacky implementation of this I've been prototyping with is here.