Короткий ответ
COMMIT фиксирует все изменения текущей транзакции безвозвратно, а ROLLBACK отменяет их полностью; явный контроль над ними нужен там, где несколько операций должны либо выполниться все вместе, либо не выполниться вообще, и где нужно корректно обработать ошибку.
Как это работает подробнее
При открытии транзакции все последующие изменения видны только внутри неё до COMMIT; при ROLLBACK СУБД откатывает их, используя MVCC-версии строк в PostgreSQL.
Пример кода
example.py
from django.db import transaction
def transfer_money(from_id, to_id, amount):
with transaction.atomic():
Account.objects.filter(id=from_id).update(balance=F("balance") - amount)
Account.objects.filter(id=to_id).update(balance=F("balance") + amount)
# При исключении внутри блока Django сделает ROLLBACK автоматическиЧто использовать на практике
- Практика. В веб-приложении типичный паттерн — одна транзакция на HTTP-запрос или бизнес-операцию: если все шаги успешны — commit в конце, если возникло исключение — rollback. ORM (Django, SQLAlchemy) предоставляют контекстные менеджеры atomic()/begin(), делающие это автоматически.
Подводные камни
- Ошибка. Забывают явный rollback после исключения, оставляя соединение в состоянии «aborted transaction»; делают commit после каждой отдельной операции там, где нужна атомарность нескольких операций вместе.