Find the bug: Celery task and card charge inside a transaction

Backend Live Coding November 13, 2026 python

Two problems.

python
 1
 2
 3
 4
 5
 6
 7
 8
 9
10
11
12
13
14
15
16
17
18
19
# ======================================================================
# Q: Find the bug.
#
# Two problems. 1) The Celery task may run before the commit, fail to find the
# order, or send an email for an order that was eventually rolled back. Fix:
# transaction.on_commit(lambda: send_confirmation_email.delay(order.id)). 2)
# Charging the card inside a transaction keeps the transaction open while we
# wait for an external system, and if it rolls back after the charge, the
# customer was charged without an order. Correct approach: commit a pending
# order, charge outside the transaction with an idempotency key, then update the
# status.
# ======================================================================

@transaction.atomic
def place_order(customer, items):
    order = Order.objects.create(customer=customer, status='pending')
    ...
    send_confirmation_email.delay(order.id)
    charge_card(order)                 # may raise an exception