默認狀況下,在Django中事務是自動提交的。當咱們運行Django內置的模板修改函數時,例如調用model.save()或model.delete()時,事務將被當即提交。這種機制和數據庫的自動提交事務機制相似。記住這裏沒有默認的回滾機制。html
對於Web請求,Django官方推薦使用中件間TransactionMiddleware來處理請求和響應中的事務。它的工做原理是這樣的:當一個請求到來時,Django開始一個事務,若是響應沒有出錯,Django提交這期間全部的事務,若是view中的函數拋出異常,那麼Django會回滾這之間的事務。數據庫
爲了實現這個特性,須要在MIDDLEWARE_CLASSES setting中添加TransactionMiddleware:django
MIDDLEWARE_CLASSES = (緩存
'django.middleware.cache.UpdateCacheMiddleware',session
'django.contrib.sessions.middleware.SessionMiddleware',ide
'django.middleware.common.CommonMiddleware',函數
'django.middleware.transaction.TransactionMiddleware',this
'django.middleware.cache.FetchFromCacheMiddleware',spa
)翻譯
順序很重要,TransactionMiddleware中間件會將置於其後的中間件都包含在事務的範圍之中(用於緩存的中間件除外,他們不受影響,例如CacheMiddleware,UpdateCacheMiddleware和FetchFromCacheMiddleware)。
另外須要注意的是,TransactionMiddleware只會影響DATABASES設置中的默認的數據庫,對於其它的數據庫,若是咱們實現事務控制的話只能用別的方案了。
若是想在更細粒度的條件下(例如在一個view函數中)控制事務,咱們能夠使用django.db.transaction。有兩種用法:
1.使用裝飾器
from django.db import transaction
@transaction.commit_on_success
def viewfunc(request):
# ...
# this code executes inside a transaction
# ...
2.使用context manager
from django.db import transaction
def viewfunc(request):
# ...
# this code executes using default transaction management
# ...
with transaction.commit_on_success():
# ...
# this code executes inside a transaction
# ...
這兩種方法均可以正常工做。不過若是使用的Python版本爲2.5而且要使用with語法的話,還需加一句
from __future__ import with_statement。
因此爲了最大的兼容性,下面的示例使用裝飾器來實現事務。
使用autocommit裝飾器能夠將view函數中的事務還原成Django默認的自動提交模式,無視全局事務的設置。
示例:
from django.db import transaction
@transaction.autocommit
def viewfunc(request):
....
@transaction.autocommit(using="my_other_database")
def viewfunc2(request):
....
顧名思義,view函數成功則提交事務,不然回滾。用法同上。
告訴Django咱們將本身控制函數中的事務處理。而且要注意,若是在視圖函數中改變了數據庫的數據而且沒有調用commit() 或rollback(),那麼將拋出TransactionManagementError異常。
示例:
from django.db import transaction
@transaction.commit_manually
def viewfunc(request):
...
# You can commit/rollback however and whenever you want
transaction.commit()
...
# But you've got to remember to do it yourself!
try:
...
except:
transaction.rollback()
else:
transaction.commit()
@transaction.commit_manually(using="my_other_database")
def viewfunc2(request):
....
本文內容所有由Django官方文檔翻譯而來,參考資料是相關的文檔。若是要查看原文或是關於事務更多的細節(例如保存點),能夠查閱。
參考資料: