我知道,django atomicity 开箱即用仅在抛出异常时才回滚事务。但是,我的脚本中捕获了几个异常,对于这些异常,我正在生成一个很好的 HTTPresponse,其中包含一些有意义的响应内容 - 但我始终确保在这种情况下的 HTTPresponse 以正确的 4xx 或 5xx HTTP 状态代码发送出去。当这样的HTTP响应发生时,我希望django回滚它到目前为止可能执行的所有数据库查询。但是,django atomicity 似乎并不基于正在发送的 HTTP 状态代码起作用,它仅基于抛出给用户的异常起作用。任何建议我如何在python 2.7
django 1.8
解决这个问题?
尝试创建一个自定义中间件来执行此操作。下面是一个基于旧TransactionMiddleware
的示例(这是未经测试的):
from django.db import transaction
class StatusCodeTransactionMiddleware(object):
"""
Rolls back the current transaction for all responses with 4xx or 5xx status
codes.
"""
def process_request(self, request):
"""Enters transaction management"""
transaction.enter_transaction_management()
def process_response(self, request, response):
"""Commits and leaves transaction management."""
if response.status_code >= 400:
if transaction.is_dirty():
# This rollback might fail because of network failure for
# example. If rollback isn't possible it is impossible to
# clean the connection's state. So leave the connection in
# dirty state and let request_finished signal deal with
# cleaning the connection.
transaction.rollback()
transaction.leave_transaction_management()
else:
if not transaction.get_autocommit():
if transaction.is_dirty():
# Note: it is possible that the commit fails. If the
# reason is closed connection or some similar reason,
# then there is little hope to proceed nicely.
# However, in some cases ( deferred foreign key checks
# for example) it is still possible to rollback().
try:
transaction.commit()
except Exception:
# If the rollback fails, the transaction state will
# be messed up. It doesn't matter, the connection
# will be set to clean state after the request
# finishes. And, we can't clean the state here
# properly even if we wanted to, the connection is
# in transaction but we can't rollback...
transaction.rollback()
transaction.leave_transaction_management()
raise
transaction.leave_transaction_management()
return response
像这样把它放在你的MIDDLEWARE_CLASSES
里:
MIDDLEWARE_CLASSES = (
"myapp.middleware.StatusCodeTransactionMiddleware",
# Other middleware...
)