New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Improve set_rollback() behaviour #6922
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -3,7 +3,7 @@ | |
""" | ||
from django.conf import settings | ||
from django.core.exceptions import PermissionDenied | ||
from django.db import connection, models, transaction | ||
from django.db import connections, models, transaction | ||
from django.http import Http404 | ||
from django.http.response import HttpResponseBase | ||
from django.utils.cache import cc_delim_re, patch_vary_headers | ||
|
@@ -63,9 +63,13 @@ def get_view_description(view, html=False): | |
|
||
|
||
def set_rollback(): | ||
atomic_requests = connection.settings_dict.get('ATOMIC_REQUESTS', False) | ||
if atomic_requests and connection.in_atomic_block: | ||
transaction.set_rollback(True) | ||
# Rollback all connections that have ATOMIC_REQUESTS set, if it looks their | ||
# @atomic for the request was started | ||
# Note this check in_atomic_block may be a false positive due to | ||
# transactions started another way, e.g. through testing with TestCase | ||
for db in connections.all(): | ||
if db.settings_dict['ATOMIC_REQUESTS'] and db.in_atomic_block: | ||
transaction.set_rollback(True, using=db.alias) | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. I'm a bit wary of this. Why is Is it possible to isolate the multi-DB fix in this PR from the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
This has a number of subtleties. More information on the specific case I had was:
The multi-DB fix comes "for free" because I have monkey patched the implementation in this PR into my client's app to fix things there and there have been no issues for 3 months now. There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Gotcha. Is there any more graceful way we can do There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Eg, is something along these lines possible instead?... for db in connections.all():
if db.settings_dict['ATOMIC_REQUESTS'] and db.in_atomic_block:
transaction.set_rollback(True, using=db.alias) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Yes that should work but it wouldn't fix my bug with testing the There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
Sorry, walk me through that. Do you mean would be broken for There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. The latter ( There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Okey dokes. So would we be able to update the PR to use the style in the comment above, and switch any test cases to There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Done. However this doesn't fix #6921. I will still need that patch in place for my client because their tests use There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. "I will still need that patch in place for my client because their tests use TestCase on @non_atomic_requests views." Okay, that seems to fall within documented expected behavior... https://docs.djangoproject.com/en/2.2/topics/testing/tools/#django.test.TransactionTestCase "Django’s TestCase class is a more commonly used subclass of TransactionTestCase that makes use of database transaction facilities to speed up the process of resetting the database to a known state at the beginning of each test. A consequence of this, however, is that some database behaviors cannot be tested within a Django TestCase class. For instance, you cannot test that a block of code is executing within a transaction, as is required when using select_for_update(). In those cases, you should use TransactionTestCase." |
||
|
||
|
||
def exception_handler(exc, context): | ||
|
@@ -223,9 +227,9 @@ def get_exception_handler_context(self): | |
""" | ||
return { | ||
'view': self, | ||
'args': getattr(self, 'args', ()), | ||
'kwargs': getattr(self, 'kwargs', {}), | ||
'request': getattr(self, 'request', None) | ||
'args': self.args, | ||
'kwargs': self.kwargs, | ||
'request': self.request, | ||
rpkilby marked this conversation as resolved.
Show resolved
Hide resolved
|
||
} | ||
|
||
def get_view_name(self): | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Perhaps we ought to be a bit more specific here and link to the https://docs.djangoproject.com/en/2.2/topics/testing/tools/#django.test.TransactionTestCase docs?