我继承了为Django 1.4编写的应用程序的一些代码。 我们需要更新代码库以使用Django 1.7,并最终将1.8作为下一个长期支持版本。
在一些地方,它使用旧样式@transaction.commit_manually
和with transaction.commit_manually:
我对一般的交易知之甚少,但我想了解它们的用途,所以我可以删除它们(如果没有必要)或将它们升级到较新的set_autocommit(False)
或等效的。
我已经理解Django中的事务管理< 1.5并不理想,对于大多数用例来说太复杂了。
数据库连接如下所示,没有特殊的事务管理。 (使用Postgres 9.3)
DATABASES = {
'default': {
'ENGINE': 'django.db.backends.postgresql_psycopg2',
'NAME': 'dbname',
'USER': 'user',
'PASSWORD': '',
'HOST': 'localhost',
'PORT': '',
}
}
没有特殊的交易中间件。
我发现以下观点特别令人费解。 (编者)
@UserRequiredDecorator
class XMLModelView(View):
@transaction.commit_manually
def get(self, request, *args, **kwargs):
user = request.user
xml_models = models.XMLModel.objects.filter(user=user).order_by('-created').all()
if xml_models:
xml_model = xml_models[0]
model = xml_model.xml_field
else:
obj = initialize_xml_model(user)
model = obj.xml_field
transaction.commit()
if isinstance(model, unicode):
model = model.encode('utf-8')
with transaction.commit_manually():
xml = XMLManipulator(model, remove_blank_text=True)
xml.insert_user_info(user)
xml.whitespace_cleanup()
model = xml.tostring()
del xml
transaction.commit()
return HttpResponse(model, content_type='text/xml')
其中initialize_xml_model
是一个获取平面xml文件(xml模型模板)并创建新XMLModel对象的函数。并且insert_user_info
将存储在用户对象中的信息插入到xml模型中。
我读这段代码的方式是
autocommit
commit_manually
transaction.commit()
会将其存储到数据库中。model
是否是一个unicode实例,然后对其进行编码(我不知道这究竟是什么)model
model
(tostring
是一个保留样式表声明的XMLManipulator方法。)xml
对象在5.之后,唯一处理db(在读取中)的是insert_user_info方法。
我真的不明白为什么在特殊交易中会发生这种情况。没有写入db?
此视图中没有其他方法,只有get。
我可能错过了一些重要的事情,随时提出任何问题或了解更多信息。
此处交易是否真的有必要,如果是,那怎么可以重写以适应新的transaction.set_autocommit
?
非常感谢任何帮助或指示。
答案 0 :(得分:6)
现在这样做的一个好方法是使用transaction.atomic。在你的例子中,我会这样做:
from django.db import transaction
@UserRequiredDecorator
class XMLModelView(View):
def get(self, request, *args, **kwargs):
with transaction.atomic():
user = request.user
xml_models = models.XMLModel.objects.filter(user=user).order_by('-created').all()
if xml_models:
xml_model = xml_models[0]
model = xml_model.xml_field
else:
obj = initialize_xml_model(user)
model = obj.xml_field
if isinstance(model, unicode):
model = model.encode('utf-8')
with transaction.atomic():
xml = XMLManipulator(model, remove_blank_text=True)
xml.insert_user_info(user)
xml.whitespace_cleanup()
model = xml.tostring()
del xml
return HttpResponse(model, content_type='text/xml')