jazzband / django-silk

Silky smooth profiling for Django
MIT License
4.32k stars 332 forks source link

Silk re-uses DB connection for failed atomic transactions. #672

Open stefan-cardnell-rh opened 10 months ago

stefan-cardnell-rh commented 10 months ago

Example:

# models.py
from django.db import models

class User(models.Model)
    name = models.CharField(max_length=200, unique=True)
# some script
from django.db import transaction, IntegrityError

User.objects.create(name='bob')

try:
    with transaction.atomic():
        User.objects.create(name='bob')
except IntegrityError as err:
    print("tried to create a duplicate!")

Since I've just created two users with the same name, I would expect IntegrityError to be raised and the print statement to be executed. Instead the error django.db.InternalError is raised with message current transaction is aborted, commands ignored until end of transaction block.

This indicates something tried to use the DB connection again after the transaction with broken (IntegrityError occured). Silky is unfortunately the one doing this; after the query fails the finally block here re-uses the same DB connection to explain the query which causes the InternalError to be raised instead of IntegrityError.