如何在MySQL数据库中使用django TransactionMiddleware
在我正在从事的一个项目中,我明确使用了以下事务:如何在MySQL数据库中使用django TransactionMiddleware,mysql,django,http,transactions,request,Mysql,Django,Http,Transactions,Request,在我正在从事的一个项目中,我明确使用了以下事务: from django.db import transaction @transaction.commit_on_succcess def some_view(request): """ Renders some view """ def some_view(request): """ Creates a user object.
from django.db import transaction
@transaction.commit_on_succcess
def some_view(request):
""" Renders some view
"""
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)
我使用的是Django1.5.5
,文档中说:
处理Web请求中的事务的推荐方法是通过Django的TransactionMiddleware将它们绑定到请求和响应阶段
它是这样工作的:当一个请求启动时,Django启动一个事务。如果生成的响应没有问题,Django将提交任何挂起的事务。如果view函数产生异常,Django将回滚所有挂起的事务
要激活此功能,只需将TransactionMiddleware添加到中间件类设置中:
我想在请求上使用事务,而不是将它们绑定到需要它的特定视图,但我对这是如何工作的有点困惑。假设我的观点如下:
from django.db import transaction
@transaction.commit_on_succcess
def some_view(request):
""" Renders some view
"""
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)
在上面的视图中,我们正在处理异常并返回响应,并且在文档中声明:
如果生成的响应没有问题,Django将提交任何挂起的事务
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
type对象,并且它引发了一个异常,那么BaseUSer
对象是使用给定数据创建的,但是UserA
type对象不是。因此,我尝试创建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)
这里根本不需要交易。如果引发IntegrityError,这意味着数据库更新甚至无法完成,因此无法回滚
如果要在单个更新失败时回滚所有更新,则事务非常有用。在我的例子中,
user
model类使用继承,因此当我尝试为父类中的字段使用无效数据创建多个对象时,会创建子类对象,但不会创建父类。。为什么会这样?你可以在我的问题中看到更新,以更好地了解我的问题,谢谢。