python 48 lines · 1 tab

Django transaction handling with atomic decorator

Priya Sharma Jan 2026
1 tab
from django.db import transaction
from django.shortcuts import get_object_or_404
from rest_framework import status
from rest_framework.decorators import api_view
from rest_framework.response import Response
from .models import Order, OrderItem, Product


@api_view(['POST'])
@transaction.atomic
def create_order(request):
    """Create an order with items atomically."""
    order = Order.objects.create(
        customer=request.user,
        status='pending'
    )

    items_data = request.data.get('items', [])

    for item_data in items_data:
        product = get_object_or_404(Product, id=item_data['product_id'])

        # Check inventory
        if product.stock < item_data['quantity']:
            # Transaction will rollback
            return Response(
                {'error': f'Insufficient stock for {product.name}'},
                status=status.HTTP_400_BAD_REQUEST
            )

        # Reduce stock
        product.stock -= item_data['quantity']
        product.save()

        # Create order item
        OrderItem.objects.create(
            order=order,
            product=product,
            quantity=item_data['quantity'],
            price=product.price
        )

    # Send email only after successful commit
    transaction.on_commit(
        lambda: send_order_confirmation.delay(order.id)
    )

    return Response({'order_id': order.id}, status=status.HTTP_201_CREATED)
1 file · python Explain with highlit

Database transactions ensure data integrity when multiple operations must succeed or fail together. I use @transaction.atomic on views or functions to wrap them in a transaction. For partial rollbacks, I use transaction.atomic() as a context manager and catch exceptions inside. The on_commit hook schedules actions (like sending emails) only after successful commit, preventing premature side effects if the transaction rolls back. I'm careful with transactions in loops to avoid locking issues. For complex workflows, I sometimes use savepoints for nested transactions.


Related snips

python
import os
import stat

for root, _dirs, files in os.walk('/etc'):
    for name in files:
        path = os.path.join(root, name)

Python security audit script for exposed risky filesystem state

python auditing host-security
by Kai Nakamura 1 tab
python
class Product(models.Model):
    name = models.CharField(max_length=200)
    slug = models.SlugField(blank=True)
    price = models.DecimalField(max_digits=10, decimal_places=2)
    cost = models.DecimalField(max_digits=10, decimal_places=2)
    margin = models.DecimalField(max_digits=5, decimal_places=2, blank=True)

Django model signals vs overriding save

django python models
by Priya Sharma 2 tabs
go
package dbutil

import (
  "context"

  "github.com/jackc/pgconn"

Retry Postgres serialization failures with bounded attempts

go postgres transactions
by Leah Thompson 1 tab
ruby
class SignupForm
  include ActiveModel::Model
  include ActiveModel::Attributes

  attribute :account_name, :string
  attribute :email, :string

Shallow Controller, Deep Params: Form Object Pattern

rails activemodel form-object
by codesnips 3 tabs
python
from django.urls import path
from . import views

app_name = 'blog'

urlpatterns = [

Django URL namespacing and reverse lookups

django python urls
by Priya Sharma 3 tabs
ruby
# Vulnerable: user input is concatenated directly into SQL.
email = params[:email]
password = params[:password]

sql = "SELECT * FROM users WHERE email = '#{email}' AND password_hash = '#{password}'"
user = ActiveRecord::Base.connection.execute(sql).first

SQL injection prevention with unsafe and safe query patterns

sql-injection owasp database
by Kai Nakamura 3 tabs

Share this code

Here's the card — post it anywhere.

Django transaction handling with atomic decorator — share card
Link copied