Zum Hauptinhalt springen
tsecurity.de LIVE
Echtzeit-Radar & Feeds
Alle RSS Feeds
👥 Community & Social
Sichere ProgrammierungThe Indie Dev Visibility Playbook: From Zero Users to Your First 100(21.09.2026 um 00:08 Uhr)
Sichere ProgrammierungBase, Chat and Reasoning Models: How Are They Different?(21.09.2026 um 00:09 Uhr)
Sichere ProgrammierungHexfield Deck is for Kanban lovers and Markdown believers(21.09.2026 um 00:20 Uhr)
Sichere ProgrammierungPermissions and Authorisation: A Practical Playbook(21.09.2026 um 00:21 Uhr)
Linux Tipps & Hardeningfilet | Terminal File Manager(20.09.2026 um 21:03 Uhr)
Linux Tipps & HardeningLooking for feedback on my Linux Distro(20.09.2026 um 21:03 Uhr)
Sichere ProgrammierungThe Indie Dev Visibility Playbook: From Zero Users to Your First 100(21.09.2026 um 00:08 Uhr)
Sichere ProgrammierungBase, Chat and Reasoning Models: How Are They Different?(21.09.2026 um 00:09 Uhr)
Sichere ProgrammierungHexfield Deck is for Kanban lovers and Markdown believers(21.09.2026 um 00:20 Uhr)
Sichere ProgrammierungPermissions and Authorisation: A Practical Playbook(21.09.2026 um 00:21 Uhr)
Linux Tipps & Hardeningfilet | Terminal File Manager(20.09.2026 um 21:03 Uhr)
Linux Tipps & HardeningLooking for feedback on my Linux Distro(20.09.2026 um 21:03 Uhr)
Intelligence View
⚡ tsecurity.de Intelligence

Preventing Overselling with Stock Reservation and select_for_update in Django

Reagiere als Erste:r — dein Feedback zählt!

Picture two users checking out the same product, with only one unit left in stock, at nearly the same moment. Without special handling, both requests can pass stock validation and both orders get created — even though only one item actually exists. This isn't a rare edge case; on a system with reasonable traffic, this kind of race condition can happen daily.

This article covers how I handled this in the checkout endpoint of my single-vendor-ecommerce project: not by decrementing stock immediately at checkout, but through a database-level locked reservation mechanism.

Why Reservation, Not Immediate Stock Deduction

The simplest way to prevent overselling is to decrement stock immediately when a user starts checkout. But this has a problem: checkout doesn't always end in a completed payment. Users can abandon the flow, sessions can expire, or payments can fail. If stock is already reduced at checkout time, the system has to constantly restore stock for every failure case — and each restoration is itself a place where miscounts or missed rollbacks can happen.

The approach I used separates two numbers: stock (the actual quantity on hand) and reserved_stock (the quantity currently "held" by an in-progress checkout). During checkout, only reserved_stock changes. The real stock only decreases once payment is confirmed through the Midtrans webhook.

With this separation, availability is calculated as stock - reserved_stock, not stock alone. This means items held by another in-progress checkout automatically become invisible as available stock to other users, without ever touching the real stock number until the transaction is actually finalized.

Implementation: Locking in _validate_and_reserve_stock

Here's the code from checkout.py that handles stock validation and reservation:

def _validate_and_reserve_stock(self, carts):
    product_ids = carts.values_list("product__id", flat=True)
    products = (
        Product.objects.select_for_update()
        .filter(id__in=product_ids)
        .order_by("id")
    )

    products_map = {product.id: product for product in products}

    for cart in carts:
        product = products_map[cart.product.id]
        available_stock = product.stock - product.reserved_stock

        if available_stock < cart.qty:
            raise serializers.ValidationError(
                {"detail": f"Stok {product.name} tidak cukup"}
            )

        product.reserved_stock += cart.qty

    Product.objects.bulk_update(products, ["reserved_stock"])

There are three things I made sure of here:

  • select_for_update() locks the relevant product rows at the database level. Until this transaction finishes, any other checkout request touching the same product has to wait — it can't read stale data and slip past stock validation.
  • .order_by("id") guarantees a consistent lock acquisition order. If two checkouts both reserve products A and B but in different order, without a consistent order_by, they could end up waiting on each other's locks — a deadlock.
  • A single bulk_update at the end, instead of calling save() per product inside the loop, so the write to the database happens as one query instead of N separate ones.

Availability is calculated from product.stock - product.reserved_stock, consistent with the separation covered in the previous section. If stock isn't sufficient, the request is rejected with a ValidationError before a single row is modified.

Ähnliche Beiträge
🔍 Verwandte News

Auch interessante Nachrichten Preventing Overselling with Stock Reservation and select_for_update in Django

Thematisch verwandte Begriffe: Preventing, Overselling, with, Stock · 6 Treffer

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Laden...

Beiträge werden geladen ...

Laden...

Videos werden geladen ...

Zum Aktualisieren ziehen
ZERO-DAY CVE-2026-93957 | A vulnerability has been found in olivier-ls PHP-FTS up to 1.1.3. This a…
Advisory →
TTS Reader • tsecurity.de Voice
tsecurity.de Icon
tsecurity.de App
Offline-Lesen, Eilmeldungen & 0ms Ladezeit

Installiere tsecurity.de direkt auf deinen Home-Bildschirm für das ultimative Vollbild-Magazinerlebnis ohne Browser-Leisten.

Nächster Beitrag
Themen-Radar & Intelligence Matrix
Echtzeit-Taxonomie nach Angriffsvektoren & Plattformen

tsecurity.de Live Threat Radar

🔴 LIVE RADAR
MONITORING
AKTIV
CVE-DATENBANK
LIVE
🔍
Community Radar & Live Chat
Sentinel Bot online • Live-Stream
Dein Cluster: Security Explorer
Match:
lädt…
Verbindung zum Community-Stream wird aufgebaut...
Bearbeitungsmodus — Senden überschreibt deine Nachricht
Community-Puls — was gerade passiert
lädt…
Aktivitäten deiner Analysten
lädt…
Neues Thema oder Eilmeldung einreichen

Reiche interessante Links, Zero-Days oder Debatten ein. Die Community entscheidet per Upvote über die Veröffentlichung.

Heiß diskutierte Einreichungen
🔖 Gespeicherte Artikel
📂 Keine gespeicherten Artikel vorhanden.
Zurück Ziehen Vor
Links: vorheriger Artikel Rechts: nächster Artikel unten: schließen
News NIS-2 Frühwarnung Tier-1 Intel ⏱️ 3 Min vor 10 Min
Artikeldaten werden geladen...

Zurück: vorheriger Vor: nächster
↗ Original-Quelle
Social Reaktionen Deine Reaktion zählt
Einstufung & Relevanz-Poll 0 Stimmen
In sozialen Netzwerken teilen 1-Klick