据我所知,django atomicity of the-box仅在异常被抛出时回滚事务。但是,有一些例外,我在我的脚本中捕获,对于那些例外,我正在为用户生成一个很好的HTTP响应和一些有意义的响应内容 - 但我总是确保在这种情况下的HTTP响应是用适当的4xx发送的或5xx HTTP状态代码。当发生这样的HTTP响应时,我希望django回滚它到目前为止可能执行的所有数据库查询。但是,django atomicity似乎并不基于正在发送的HTTP状态代码来执行,它仅基于抛出给用户的异常来起作用。有关如何在django 1.8
python 2.7
上解决此问题的任何建议?
答案 0 :(得分:1)
尝试创建可以执行此操作的自定义中间件。这是一个based on the old 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...
)