Database transaction
This is the 9th day of my participation in the August More Text Challenge. For details, see:August is more challenging
Django provides several ways to control database transactions.
Before calling the attempt method, Mr. Django makes a transaction. If the response is generated properly, Django commits the transaction. If the view is abnormal, Django will roll back the transaction.
You can use restore points in your view code to perform subtransactions, usually using the atomic() context manager. However, by the end of the view, either all the changes have been committed or none have been committed.
Note that only the view is restricted to execution within the transaction. In the same way that the middleware runs outside of the transaction, the render template response runs outside of the transaction.
1. Use transaction descriptions in Django
In saving order data, data changes involving multiple tables should be made in a single transaction, that is, they either succeed together or fail together.
By default, database transactions in Django are automatically committed every time a database operation is performed. We need to control the execution flow of the database transaction ourselves in the save order.
In Django, you can define a transaction through the use of the django.db.transaction module, which provides two uses for atomic
-
Decoration method
from django.db import transaction @transaction.atomic# An error is reported def viewfunc(request) : This code is executed in a transaction.Copy the code
-
The with statement
from django.db import transaction def viewfunc(request) : # This part of the code is not part of the transaction and will be automatically committed by Django.with transaction.atomic(): This part of the code will be executed in the transaction.Copy the code
In Django, savepoints are also supported. You can create savepoints within a transaction to record a specific state of the data, which can be reverted to in the event of a database error
from django.db import transaction
# Create savepoints
save_id = transaction.savepoint()
# Rollback to savepoint
transaction.savepoint_rollback(save_id)
Commit all database transaction operations from the savepoint to the current state
transaction.savepoint_commit(save_id)
Copy the code
2. Explicitly control transactions
Atomic (using = None, savepoint = True) ¶
Atomicity is a defining attribute of a database transaction. Atomic allows you to create blocks of code to keep your database atomic. If the block is successfully created, the change is committed to the database. If there is an exception, the change is rolled back.
Atomic blocks can be nested. In this example, when the inner block completes successfully, if an exception is thrown later in the outer block, it can still be rolled back to the original effect.
Atomic can be used as a decorator
Method one:
from django.db import transaction
@transaction.atomic
def viewfunc(request) :
do_stuff()
Copy the code
Method 2:
from django.db import transaction
def viewfunc(request) :
do_stuff()
with transaction.atomic():
do_more_stuff()
Copy the code
Method 3:
from django.db import IntegrityError, transaction
@transaction.atomic
def viewfunc(request) :
create_parent()
try:
with transaction.atomic():
generate_relationships()
except IntegrityError:
handle_exception()
add_children()
Copy the code
After submission
Operations related to the current database transaction need to be performed, but only if the transaction is successfully committed. Examples may include tasks in tasks, email alerts, or cache invalidation.
Django provides the on_commit () function to register the callback function that should be executed after a successful commit transaction:
on_commit
(func.using=None)
Pass any function (no arguments) to on_commit()
from django.db import transaction
def do_something() :
pass # send a mail, invalidate a cache, fire off a Celery task, etc.
transaction.on_commit(do_something)
Copy the code
You can also use lambda:: to wrap functions
transaction.on_commit(lambda: some_celery_task.delay('arg1'))
Copy the code
Note: Asynchronous tasks are performed only after the transaction is successfully committed