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
Fixed #25939 -- Removed transaction from QuerySet.update_or_create's save(). #5804
Conversation
This is a second PR. You can see first one here: #5790 |
@@ -495,8 +494,7 @@ def _create_object_from_params(self, lookup, params): | |||
Used by get_or_create and update_or_create | |||
""" | |||
try: | |||
with transaction.atomic(using=self.db): | |||
obj = self.create(**params) | |||
obj = self.create(**params) |
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.
I think this one requires a savepoint, but create() calls save(), and save has savepoint=False.
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.
Also, the atomic(savepoint=False) is really cheap (no DB action at all) when used inside another atomic. So, the atomic() here makes the atomic() inside save cheap enough to not matter (of course, benchmarks tell the truth).
Thanks, I'll update PR according to your comments. Just wanted to say that I'm getting "OperationalError: database is locked" exception without first hunk applied. It happens on get_or_create call. |
If you're getting Please seek help:
|
Thanks for your suggestion. I can only say that with this patch applied I can't reproduce the error. There should be a reason for that. Suggesting to stop using sqlite is a work around, not a solution from my point of view. |
Updated PR according to reviewer suggestions. Please, merge if you don't mind. |
aaugustin, thank you for the info. I hope it will help me to find the reason for the issue. Just to be clear. The issue is gone when both hunks of original patch are applied. It's still there with moving save out of transaction.atomic context. I'll check if another hunk alone fixes it or not. |
aaugustin, I've read sqlite FAQ before. what's written there doesn't explain the fact that I'm getting dozens of 'database is locked' issues and they're gone if I move obj = self.create(**params) out of transaction.atomic context in query.py Any other ideas where to look and what potentially could be the reason? |
I have no idea about your use case, your code, or the kind of concurrency you're facing. If you could reproduce this with a minimal example and a simulate load, then we could benchmark it. |
yep, makes sense. I'll try to sketch some example. meanwhile feel free to merge this commit. I'll create new PR when I get the data. Thank you, |
Could you add a mention in the 1.10 release notes "Backwards-incompatible" changes section as requested by Aymeric? "This may affect query counts tested by assertNumQueries in TransactionTestCase which should be mentioned in the release notes." |
There is no need to wrap call of save method in transaction.atomic as it's already done down the call stack in Model.save_base method.
reopen as it was closed by mistake. |
Updated release notes as suggested. |
merged in 423b3af, thanks! |
There is no need to wrap calls of create and save methods in
transaction.atomic as it's already done down the call stack in
Model.save_base method.