-
-
Notifications
You must be signed in to change notification settings - Fork 6.9k
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
Adding transaction rollback to exception_handler #1204
Conversation
Another solution is move it to a middleware (The exception handling, and leave the rollback to the transaction middelware), that's probably more correct on django arquitechture, but harder to modify and configure by the DRF user. And of course the final version will come with tests and documentation :) |
Other thing, the use of transaction api directly have a deprecation warning in django 1.6, this give an extra point to use directly the middleware for easy compatibility between django versions from 1.3 to 1.6 (the supported versions by DRF) |
Not obvious to me what the implications of this are. |
This is a PR to show the idea, but not to merge, I will work more on it if you find it useful. The transaction middleware only rollback on commit fails or on exception handling, because DRF handle the API Exceptions, thats not rollback the transaction. I need to know if you find acceptable to move to a Middleware the API Exception handling, or if you prefer a solution more like the solution exposed in the PR. Of course i will test it with and without TransactionMiddleware, and with normal and API exceptions. |
Something like this looks okay to me.
Rather than include it in the exception_handler function, we might want to include it here: So that we ensure it only runs if we've suppressed an exception. Keeps user code simpler, as users shouldn't need to worry about if it's something they need to be concerned about in their exception handler. |
Sounds good :) I will do the changes and add some unit tests. |
Looks like the tests are failing on this as it currently stands. |
Yes,the test are failing. I pushed changes but they aren`t ready. I will comment here when the PR is ready. |
Great, thanks @jespino. |
+1. |
@adamJLev if anyone wants to take up getting the patch to pass the tests that'd be appreciated. |
Shouldn't there be decorators to the views so that they are marked for transactions ? |
@xordoquy I think something like this should be included: https://gist.github.com/adamJLev/7e9499ba7e436535fd94 (found on Google, don't know if it works) but it seems like it might, given this documentation from Django: https://docs.djangoproject.com/en/dev/topics/class-based-views/intro/#decorating-the-class and if it doesn't, something that does is probably not much different. |
@dustinfarris @xordoquy Works well, I wrote that and we have been running it in production for months now 👍 |
@tomchristie do we agree DRF should provide the decorator to mark the views as atomic ? |
I don't think we should provide it as a decorator, but it looks like we probably should provide it. Perhaps configured by a I'm still slightly confused as to why this isn't considered an issue with non-API views, or say, other packages that provide generic view classes or similar? I'm probably missing something obvious there having not looked at this ticket for a bit, but it'd be tremendous if someone could walk through it. |
This is probably because exception have a different workflow. |
@xordoquy sounds about right, if anyone has suggestions on good wordings / documentation explaining the behaviour briefly and clearly, that'd be helpful. We might want to consider this for the 2.4 release, right? See #1770. That's probably already good to get merged into master, but doesn't mean we can't then leave the release to PyPI hanging for a few more days while this is also resolved & some more folks get to test. |
Milestone set to 2.4, not as a definite, but for consideration prior to release. |
transaction.set_rollback(True) # Django 1.6+ | ||
elif transaction.is_managed(): | ||
# If running <=1.5 and TransactionMiddleware is installed then force it's rollback behavior. | ||
TransactionMiddleware().process_exception(request, None) |
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.
We ought to put branching code like this in the compat
module.
eg introduce a set_rollback(transaction)
function there that performs this behavior.
Either one or both of the last two would be okay - doesn't necessarily need to be both. |
Note the updates against #1787 - If you're following this thread, you probably want to be on that instead now. |
This PR is to show you the idea, there are other ways to implement it (like, for example, another exception class named RollbackAPIException), anyway I find the interference of APIException capture with the rollback of django transaction middleware on exceptions, a little bit dangerous.
If you find it useful, I can implement with the RollbackAPIException, which is more backward compatible.