【发布时间】:2023-04-07 12:25:01
【问题描述】:
在我正在进行的一个项目中,我明确地使用如下事务:
from django.db import transaction
@transaction.commit_on_succcess
def some_view(request):
""" Renders some view
"""
我正在使用 Django 1.5.5,在文档中它说:
在 Web 请求中处理事务的推荐方法是通过 Django 的 TransactionMiddleware 将它们绑定到请求和响应阶段。
它是这样工作的:当一个请求开始时,Django 开始一个事务。如果生成的响应没有问题,Django 将提交任何未决事务。如果视图函数产生异常,Django 会回滚所有待处理的事务。
要激活此功能,只需将 TransactionMiddleware 中间件添加到您的 MIDDLEWARE_CLASSES 设置:
我想在请求中使用事务,而不是将它们绑定到需要它的特定视图,但我对它的工作原理有点困惑。假设我的观点如下:
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 会提交任何未决事务。
问:即使引发异常,事务是否会在上述视图中提交?
如果我们想在一个请求中创建多个对象,并且只想回滚一个引发异常但提交所有其他的条目怎么办?因此,例如,我们从文件中读取数据,并且对于要创建用户对象的每一行,我们希望将所有用户插入到数据库中,但引发错误的用户除外:
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)
问:在这种情况下交易将如何运作?在这里显式使用事务会更好吗?
更新:
就我而言,我使用的是继承模型类。示例:
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)
【问题讨论】:
标签: mysql django http transactions request