skylark
skylark copied to clipboard
uncaught exception within Transaction context unexpectedly commits partial work
When an uncaught exception happens inside a transaction I expect the transaction to be rolled back, what happens instead is that partial results are committed, thus modifications in Transaction
context manager guarded code are not atomic for the outside world.
To back up my claim on behavior it is an example in 3. A template for committing or rolling back a database
in PEP 343 -- The "with" Statement and here are two other python transaction context manager __exit__
codes:
- https://github.com/Xof/xact/blob/18ea837c6ff8ef41d236bd2569eedc8093532dfd/xact.py#L50
- https://github.com/django/django/blob/0ed7d155635da9f79d4dd67e4889087d3673c6da/django/db/transaction.py#L110
I propose a solution of modifying Transaction.__exit__
so that a .rollback()
is called instead of .commit()
when except_tp
is not None
.
You might check out peewee -- the transaction context manager is implemented as you describe. Much of the code in this project is, as far as I can tell, lifted from peewee anyways so you hopefully won't have trouble.
@coleifer I am aware of peewee and will consider again it in the future. Should this lack of attribution happen to me I would be upset as well (#34).
@hit9 this issue is still relevant to the code being discussed, for future users/users looking at the project repo/ please add references to peewee and reopen this issue unless fixed!