|
1 | 1 | # Django Subatomic |
2 | 2 |
|
3 | | -Django Subatomic enables precise control over transaction logic in Django. |
| 3 | +Subatomic splits [Django's `atomic`][atomic] into a suite of more specific utilities. |
| 4 | +It offers precise control over transaction logic in Django projects |
| 5 | +and transaction simulation in tests. |
4 | 6 |
|
5 | | -* To read about why Django Subatomic exists, see [Django's Atomic](why.md). |
6 | | -* For how to use Django Subatomic, see [Transactions and Savepoints](transactions-savepoints-and-atomic.md). |
| 7 | +## Installation |
| 8 | + |
| 9 | +```sh |
| 10 | +pip install django-subatomic |
| 11 | +``` |
| 12 | + |
| 13 | +## Quick comparison |
| 14 | + |
| 15 | +Subatomic's utilities don't exactly map one-to-one to Django's transactions API, |
| 16 | +but the table below is broadly representative. |
| 17 | +See the footnotes for some nuance |
| 18 | +and the linked API docs for full details. |
| 19 | + |
| 20 | +Desired outcome | Django | Subatomic |
| 21 | +--- | --- | --- |
| 22 | +Create transaction | `atomic()`[^atomic] | [`transaction()`][django_subatomic.db.transaction][^transaction] |
| 23 | +Create savepoint | `atomic()`[^atomic] | [`savepoint()`][django_subatomic.db.savepoint][^savepoint] |
| 24 | +Run in a transaction | `atomic()`[^atomic] | [`transaction_required()`][django_subatomic.db.transaction_required][^transaction_required] |
| 25 | +Fail if in a transaction | `assert not connection.in_atomic_block` | [`@durable`][django_subatomic.db.durable][^durable] |
| 26 | +Run after transaction completes | `transaction.on_commit()` | [`run_after_commit()`][django_subatomic.db.run_after_commit][^run_after_commit] |
| 27 | + |
| 28 | + |
| 29 | +## Further reading |
| 30 | + |
| 31 | +- [Subatomic's features](features.md). |
| 32 | + |
| 33 | +- [The difference between transactions and savepoints](transactions-savepoints-and-atomic.md). |
| 34 | + |
| 35 | +- [Problems with Django's `atomic`](why.md). |
| 36 | + |
| 37 | +- [Testing after-commit callbacks](testing-after-commit-callbacks.md). |
| 38 | + |
| 39 | + |
| 40 | +[^atomic]: |
| 41 | + Django's `atomic` creates a savepoint or a transaction depending on two factors: |
| 42 | + |
| 43 | + - The arguments passed to it (`durable=` and `savepoint=`). |
| 44 | + - If a database transaction is already open. |
| 45 | + |
| 46 | + For more info, see [Django's atomic](why.md). |
| 47 | + |
| 48 | +[^transaction]: |
| 49 | + Unlike `atomic`, |
| 50 | + which will create a savepoint if a transaction is already open, |
| 51 | + `transaction` ensures the database is not already in a transaction. |
| 52 | + |
| 53 | +[^savepoint]: |
| 54 | + Unlike `atomic`, |
| 55 | + which may create a transaction, |
| 56 | + `savepoint` ensures the database has an active transaction. |
| 57 | + |
| 58 | +[^transaction_required]: |
| 59 | + This ensures that some code is atomic |
| 60 | + by requiring that a transaction is already open. |
| 61 | + Unlike `atomic`, this never creates a transaction or a savepoint. |
| 62 | + |
| 63 | +[^durable]: |
| 64 | + This ensures that code |
| 65 | + may choose to manage its own transactions |
| 66 | + by requiring that a transaction is not already open. |
| 67 | + |
| 68 | + Note: This shouldn't be confused with `atomic(durable=True)`; |
| 69 | + this never creates a transaction. |
| 70 | + |
| 71 | +[^run_after_commit]: |
| 72 | + Unlike `transaction.on_commit()`, |
| 73 | + this prevents misleading code |
| 74 | + by raising an error if there is no transaction open. |
| 75 | + |
| 76 | + |
| 77 | +[atomic]: https://docs.djangoproject.com/en/stable/topics/db/transactions/#django.db.transaction.atomic |
0 commit comments