Django не использует атомарные транзакции по умолчанию?

Я прочитал документацию django о транзакциях базы данных.

Затем, в этом разделе говорится:

Поведение Django по умолчанию - это работа в режиме автокоммита. Каждый запрос немедленно фиксируется в базе данных, если только не активна транзакция.

Значит, как говорится в разделе, Django не использует атомарные транзакции по умолчанию?

Итак, если Django не использует атомарные транзакции по умолчанию, при обновлении данных в Django Admin Panel, может возникнуть Race Condition, верно? Если не установить атомарные транзакции вручную.

enter image description here

Django не использует Atomic Transaction по умолчанию для Django views, в то время как Django использует Atomic Transaction по умолчанию для Django admin.

Используя PostgreSQL, я проверил, используется ли Atomic Transaction по умолчанию или нет для Django представлений с помощью приведенного ниже кода. Запросы "SELECT", "INSERT", "UPDATE" и "DELETE" выполняются кодом класса "Animal" в представлении "test()" на "views.py" как показано ниже. *Вы также можете посмотреть мой ответ , в котором экспериментируется, используется ли Atomic Transaction для Django admin по умолчанию или нет:

# "store/views.py"

from django.http import HttpResponse
from .models import Animal

def test(request):

    animal = Animal.objects.all() # For "SELECT" query
    print(animal) # Needed to run "SELECT" query

    Animal(name='Dog').save() # For "INSERT" query

    Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query

    Animal.objects.filter(name="Cat").delete() # For "DELETE" 

    return HttpResponse("Test")

А это "urls.py" ниже:

# "store/urls.py"

from django.urls import path
from . import views

app_name = "store"

urlpatterns = [
    path('test/', views.test, name="test"),
]

Затем я открываю url "http://localhost:8000/store/test/" для запуска "тестового" представления как показано ниже:

enter image description here

Теперь, между "BEGIN" и "COMMIT" запросами, только "DELETE" запрос выполняется кодом класса "Animal" в "test()" представлении..., Таким образом, Atomic Transaction не используется для Views по умолчанию. *Эти журналы ниже являются журналами запросов PostgreSQL. Вы можете проверить в PostgreSQL, как регистрировать SQL-запросы с транзакционными запросами, такими как "BEGIN" и "COMMIT":

enter image description here

Далее, для представления "test()" , я поместил декоратор "@transaction.atomic" как показано ниже:

# "store/views.py"

from django.http import HttpResponse
from .models import Animal

@transaction.atomic # Here
def test(request):
    
    animal = Animal.objects.all() # For "SELECT" query
    print(animal) # Needed to run "SELECT" query

    Animal(name='Dog').save() # For "INSERT" query

    Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query

    Animal.objects.filter(name="Cat").delete() # For "DELETE" 

    return HttpResponse("Test")

Ор, для представления "test()" , я ставлю "with transaction.atomic():", как показано ниже:

# "store/views.py"

from django.http import HttpResponse
from .models import Animal

def test(request):

    with transaction.atomic(): # Here
    
        animal = Animal.objects.all() # For "SELECT" query
        print(animal) # Needed to run "SELECT" query

        Animal(name='Dog').save() # For "INSERT" query

        Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query

        Animal.objects.filter(name="Cat").delete() # For "DELETE" 

        return HttpResponse("Test")

Ор, для "test()" view, я поместил 'ATOMIC_REQUESTS': True в настройках PostgreSQL в "settings.py" как показано ниже:

# "core/settings.py"

DATABASES = {
    'default':{
        'ENGINE':'django.db.backends.postgresql',
        'NAME':'postgres',
        'USER':'postgres',
        'PASSWORD':'admin',
        'HOST':'localhost',
        'PORT':'5432',
        'ATOMIC_REQUESTS': True, # Here
    }
}

Затем я открываю url "http://localhost:8000/store/test/" для запуска "тестового" представления как показано ниже:

enter image description here

Теперь, между запросами "BEGIN" и "COMMIT" , "SELECT", "INSERT", "UPDATE" и "DELETE" запросы выполняются кодом класса "Animal" в представлении "test()" . Итак, теперь Atomic Transaction работает:

enter image description here

Далее, для представления "test()" я поместил оба декоратора "@transaction.atomic" и "with transaction.atomic():" как показано ниже:

# "store/views.py"

from django.http import HttpResponse
from .models import Animal

@transaction.atomic # Here
def test(request):
    
    with transaction.atomic(): # Here
        
        animal = Animal.objects.all() # For "SELECT" query
        print(animal) # Needed to run "SELECT" query

        Animal(name='Dog').save() # For "INSERT" query

        Animal.objects.filter(name="Dog").update(name="Cat") # For "UPDATE" query

        Animal.objects.filter(name="Cat").delete() # For "DELETE" 

        return HttpResponse("Test")

И, я также поместил "ATOMIC_REQUESTS": True в настройках PostgreSQL в "settings.py" как показано ниже:

# "core/settings.py"

DATABASES = {
    'default':{
        'ENGINE':'django.db.backends.postgresql',
        'NAME':'postgres',
        'USER':'postgres',
        'PASSWORD':'admin',
        'HOST':'localhost',
        'PORT':'5432',
        'ATOMIC_REQUESTS': True, # Here
    }
}

Затем я открываю url "http://localhost:8000/store/test/" для запуска "тестового" представления как показано ниже:

enter image description here

Теперь, между запросами "BEGIN" и "COMMIT" , выполняются 2 запроса "SAVEPOINT" и 2 запроса "RELEASE SAVEPOINT" , как показано ниже:

enter image description here

Вернуться на верх