django數據庫事務使用記錄

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

相關文章
相關標籤/搜索