Django не использует атомарные транзакции по умолчанию?
Я прочитал документацию django о транзакциях базы данных.
Затем, в этом разделе говорится:
Поведение Django по умолчанию - это работа в режиме автокоммита. Каждый запрос немедленно фиксируется в базе данных, если только не активна транзакция.
Значит, как говорится в разделе, Django не использует атомарные транзакции по умолчанию?
Итак, если Django не использует атомарные транзакции по умолчанию, при обновлении данных в Django Admin Panel, может возникнуть Race Condition, верно? Если не установить атомарные транзакции вручную.
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/" для запуска "тестового" представления как показано ниже:
Теперь, между "BEGIN" и "COMMIT" запросами, только "DELETE" запрос выполняется кодом класса "Animal" в "test()" представлении..., Таким образом, Atomic Transaction не используется для Views по умолчанию. *Эти журналы ниже являются журналами запросов PostgreSQL. Вы можете проверить в PostgreSQL, как регистрировать SQL-запросы с транзакционными запросами, такими как "BEGIN" и "COMMIT":
Далее, для представления "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/" для запуска "тестового" представления как показано ниже:
Теперь, между запросами "BEGIN" и "COMMIT" , "SELECT", "INSERT", "UPDATE" и "DELETE" запросы выполняются кодом класса "Animal" в представлении "test()" . Итак, теперь Atomic Transaction работает:
Далее, для представления "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/" для запуска "тестового" представления как показано ниже:
Теперь, между запросами "BEGIN" и "COMMIT" , выполняются 2 запроса "SAVEPOINT" и 2 запроса "RELEASE SAVEPOINT" , как показано ниже:




