2014-01-21 25 views
0

在其中一個項目我的工作,我現在用的是交易明確如下:如何使用Django TransactionMiddleware與MySQL數據庫

from django.db import transaction 

@transaction.commit_on_succcess 
def some_view(request): 
    """ Renders some view 
    """ 

我使用Django 1.5.5並在文檔,它說:

The recommended way to handle transactions in Web requests is to tie them to the request and response phases via Django’s TransactionMiddleware.

It works like this: When a request starts, Django starts a transaction. If the response is produced without problems, Django commits any pending transactions. If the view function produces an exception, Django rolls back any pending transactions.

To activate this feature, just add the TransactionMiddleware middleware to your MIDDLEWARE_CLASSES setting:

我想在請求上使用事務,而不是將它們綁定到需要它的特定視圖,但我對這種工作方式有點困惑。說我有一個觀點如下:

def some_view(request): 
    """ Creates a user object. 
    """ 

    context = {} 
    first_name = request.POST['first_name'] 
    last_name = request.POST['last_name'] 
    email = request.POST['email'] 

    try: 
     create_user(first_name, last_name, email) 
     context['success'] = 'User %s was added to the database.' % (first_name) 
    except IntegrityError, err: 
     context['failure'] = 'An error occurred while adding user to the database: %s' % (str(err)) 
    except Exception, err: 
     context['failure'] = '%s' % (str(err)) 

    return json_response(context) 

在上述觀點,我們正在處理異常和返回響應,並在文檔它指出:

If the response is produced without problems, Django commits any pending transactions.

Q:該交易將是在上述觀點中承諾即使引發異常?

如果我們想要在單個請求中創建多個對象,並且只想回滾引發異常但提交其他所有內容的單個條目,該怎麼辦?因此,例如,我們從文件中讀取數據,併爲我們想創建一個用戶對象的每一行,我們希望所有的用戶將被插入到數據庫除外引發錯誤的那些:

def some_view(request): 
    """ Creates a user object. 
    """ 

    context = {} 
    data = # Read from file 

    for row in data: 
     first_name, last_name, email = row.split(",") 

     try: 
      create_user(first_name, last_name, email) 
      context['success'] = 'User %s was added to the database.' % (first_name) 
     except IntegrityError, err: 
      context['failure'] = 'An error occurred while adding user to the database: %s' % (str(err)) 
     except Exception, err: 
      context['failure'] = '%s' % (str(err)) 

    return json_response(context) 

Q:在這種情況下,交易如何運作?在這裏明確使用交易是否更好?

更新

在我來說,我使用的是繼承的模型類。例如:

class BaseUser(models.Model) 
    first_name = models.CharField(max_length=100) 
    last_name = models.CharField(max_length=100) 
    email = models.EmailField(max_length=100, unique=True) 


class UserA(BaseUser): 
    phone = models.BigIntegerField() 
    type = models.CharField(max_length=32) 

因此,在情況下,我想創建使用上述視圖UserA型對象,並將其引發了異常,該BaseUSer對象與給定的數據創建,但UserA類型的對象是沒有的。所以,我想要做的是創建TypeA對象或不要提交任何更改。目前我手動使用事務(如下),它似乎工作正常,只是我想切換到使用HTTP請求上的事務。

from django.db import transaction 


transaction.commit_on_success() 
def some_view(request): 
    """ Creates a user object. 
    """ 

    context = {} 
    data = # Read from file 

    for row in data: 
     first_name, last_name, email = row.split(",") 

     try: 
      sid = transaction.savepoint() 
      create_user(first_name, last_name, email) 
      context['success'] = 'User %s was added to the database.' % (first_name) 
      transaction.savepoint_commit() 
     except IntegrityError, err: 
      context['failure'] = 'An error occurred while adding user to the database: %s' % (str(err)) 
      transaction.savepoint_rollback() 
     except Exception, err: 
      transaction.savepoint_rollback() 
      context['failure'] = '%s' % (str(err)) 

    return json_response(context) 

回答

0

您在這裏不需要交易。如果發生IntegrityError,那意味着數據庫更新甚至無法完成,所以沒有任何東西可以回滾。

交易很有用,如果你想回滾所有更新,如果一個失敗。

+0

那麼在我的情況下,'user'模型類使用繼承,所以當我嘗試使用父類中的字段的無效數據創建多個對象時,會創建子類對象,但父類不是。爲什麼 ? – Amyth

+0

您可以在我的問題中看到更新以更好地瞭解我的問題,謝謝。 – Amyth

相關問題