Skip to content
thesarfo

Note

Database Transactions

Wrapping related saves in @transaction.atomic() (or a with block) so an Order and its OrderItems either both save or neither does.

views 0

Sometimes we want to make changes to the db at the same time, for related fields. We use what is called a transation. For instance, we have an Order and OrderItem table, an OrderItem should only exist when there is an order. so we need to create an Order first, and then add the order items.

from store.models import Order, OrderItem
def say_hello(request):
order = Order()
order.customer_id = 1
order.save()
item = OrderItem()
item.name = 'Fruit'
item.product_id = 1
item.quantity = 1
item.unit_price = 1
item.save()

The above implementation works, but is flawed. What if something happens during saving and we couldnt save our order item. This means we will have an order without an order item which is not good. So we can wrap them in a transaction(Atomic of the ACID principles) such that either both the order and orderitems are saved together in the database, or they are not saved at all. see below

from django.db import transaction
@transaction.atomic()
def say_hello(request):
order = Order()
order.customer_id = 1
order.save()
item = OrderItem()
item.name = 'Fruit'
item.product_id = 1
item.quantity = 1
item.unit_price = 1
item.save()

This works. Now lets say we have some other code in the function before the order and orderitem that we want to perform the transaction on. we can do it this way

from django.db import transaction
def say_hello(request):
#other code here
#nd here too
with transaction.atomic():
'''we indent our transaction in this with block'''
order = Order()
order.customer_id = 1
order.save()
item = OrderItem()
item.name = 'Fruit'
item.product_id = 1
item.quantity = 1
item.unit_price = 1
item.save()