django版本:1.8+, 數據庫: mysqlpython
事務:事務是一系列數據庫語句的原子集。即便程序在運行時崩潰了,數據庫能夠確保事物集中的全部變動要麼都被提交,要麼都被放棄。mysql
咱們知道mysql數據庫支持多種存儲引擎。如MYISAM和innodb。在mysql5.5.5以後,innodb爲mysql的默認存儲引擎。innodb特色就是支持事務操做和外鍵約束。這裏記錄下django對數據庫事務的api使用,假設咱們使用的是innodb。若是數據庫不支持事務操做的話, 那麼Django會一直工做在自動提交模式 : 語句一旦被調用就會被執行和提交。sql
1. 能夠在settings.py文件中的數據庫配置加上配置項ATOMIC_REQUESTS:True。 這樣的話,django在調用一個view裏面的方法以前,django開始一個事務若是view執行的響應沒有問題, Django就會提交這個事務。若是在view這裏產生一個異常,Django就會回滾此次事務。數據庫
配置:django
DATABASES = { 'default': { 'ENGINE': 'django.db.backends.mysql', 'NAME': 'db_name', # Or path to database file if using sqlite3. # The following settings are not used with sqlite3: 'USER': 'user', 'PASSWORD': 'password', 'HOST': '', # Empty for localhost through domain sockets or '127.0.0.1' for localhost through TCP. 'PORT': '', # Set to empty string for default. # 'ATOMIC_REQUESTS': True , # 當須要將每一個HTTP 請求封裝在一個數據庫事務中時,設置它爲True # 'AUTOCOMMIT': False, # 若是你須要禁用Django 的事務管理並本身實現,設置它爲False。默認爲True, # 'CONN_MAX_AGE': 0, # 數據庫鏈接的存活時間,以秒爲單位。0 表示在每一個請求結束時關閉數據庫鏈接 —— 這是Django 的歷史遺留行爲, None 表示無限的持久鏈接。 }, 'OPTIONS': { 'init_command': 'SET storage_engine=INNODB', 'charset': 'utf8mb4' } }
若是某個視圖不想有事務管理,能夠經過@non_atomic_requests()修飾view函數,這樣的話,這個view函數執行邏輯就是autocommit。
api
@non_atomic_requests() def helloworld(request): if 'method' in request.GET: if request.GET['method'] == 'new': Book.objects.create(title=request.GET['title']) if request.GET['title'] == 'error': raise Exception("error") return HttpResponse("helloworld")
這樣的話,這個views將autocommit,Book.objects.create(title=request.GET['title'])執行時將直接commit到數據庫。dom
2. 不經過上面的方式配置ATOMIC_REQUESTS。django的django.db.transaction提供了多個方式管理事務。主要的是atomic。咱們可使用@atomic修飾相應的視圖函數,或者可使用上下文管理器只在一段代碼段進行事務管理。socket
@atomic() def helloworld(request): if 'method' in request.GET: if request.GET['method'] == 'new': Book.objects.create(title=request.GET['title']) if request.GET['title'] == 'error': raise Exception("error") return HttpResponse("helloworld")
請求helloworld?method=new&title=error的話。Book.objects.create(title=request.GET['title'])將不會提交到數據庫。函數
atomic()能夠多層嵌套。最外面一層atomic()執行時,django將在數據庫鏈接上設置in_atomic_block爲True,使用set_autocommit(False)開始一個事務。非最外層的atomic()執行時,由於in_atomic_block已經爲True,就會savepoint()建立保存點。 推出時,也是一層層commit或者rollback。atom