-
Notifications
You must be signed in to change notification settings - Fork 3.5k
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
Fix race condition when deleting schedules #15259
Conversation
If more than one schedule for a unified job template is removed at once, a race condition can arise. example scenario: delete schedules with ids 7 and 8 - unified job template next_schedule is currently 7 - on delete of schedule 7, update_computed_fields will try to set next_schedule to 8 - but while this logic is occurring, another transaction is deleting 8 This leads to a db IntegrityError The solution here is to call select_for_update() on the next schedule, so that 8 cannot be deleted until the transaction for deleting 7 is completed. Signed-off-by: Seth Foster <[email protected]>
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.
Two issues:
- Don't
select_for_update
until afternext_schedule
is set. Becauseupdate_computed_fields
is expected to be called frequently without regard for the performance issues this will cause, which would be intense with your changes as-is. - If you do this in auto-commit mode it throws error
TransactionManagementError: select_for_update cannot be used outside of a transaction.
What you wrote will work for requests but is highly likely to break random code that runs as tasks / commands. I don't know how you will solve this, but you'll figure it out. Just paste some manual verification because it can't be verified in our (transactional) tests.
Signed-off-by: Seth Foster <[email protected]>
@AlanCoding I think I addressed your concerns, let me know select_for_update works on object managers, not objects, so we have to re-query here This is after the logic of checking whether we need to save next_schedule, so should be infrequently done anyways. in autocommit mode, works just fine (for this test, I added a log statement to highlight that I'm in autocommit mode)
|
Yeah, expected. |
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.
Haven't verified as fix for the issue, but I expect it to work.
If more than one schedule for a unified job template is removed at once, a race condition can arise. example scenario: delete schedules with ids 7 and 8 - unified job template next_schedule is currently 7 - on delete of schedule 7, update_computed_fields will try to set next_schedule to 8 - but while this logic is occurring, another transaction is deleting 8 This leads to a db IntegrityError The solution here is to call select_for_update() on the next schedule, so that 8 cannot be deleted until the transaction for deleting 7 is completed. Signed-off-by: Seth Foster <[email protected]>
If more than one schedule for a unified job template is removed at once, a race condition can arise. example scenario: delete schedules with ids 7 and 8 - unified job template next_schedule is currently 7 - on delete of schedule 7, update_computed_fields will try to set next_schedule to 8 - but while this logic is occurring, another transaction is deleting 8 This leads to a db IntegrityError The solution here is to call select_for_update() on the next schedule, so that 8 cannot be deleted until the transaction for deleting 7 is completed. Signed-off-by: Seth Foster <[email protected]>
SUMMARY
issue #9548
If more than one schedule for a unified job template is removed at once, a race condition can arise.
example scenario: delete schedules with ids 7 and 8
This leads to a db IntegrityError
The solution here is to call select_for_update() on the next schedule, so that 8 cannot be deleted until the transaction for deleting 7 is completed.
ISSUE TYPE
COMPONENT NAME