DB: Select upon delete for allocations

When an allocation has been created, it is still being created
in the background. The client may request deletion of the
allocation *prior* to the creation of the allocation is entirely
completed. That is fine, but the challenge is we may encounter a
locked row if we're asked to delete while in process.

So, we'll query with with_for_update[0] which should be held until
the lock is released, which is only released when the original
locking transaction closes out[1][2].

[0]: https://docs.sqlalchemy.org/en/14/core/selectable.html#sqlalchemy.sql.expression.GenerativeSelect.with_for_update
[1]: https://dev.mysql.com/doc/refman/5.7/en/select.html
[2]: https://dev.mysql.com/doc/refman/5.7/en/innodb-locking-reads.html

Change-Id: I0b68f054c951655b01f0cd776feb5a8c768471ab
Closes-Bug: #2028866
This commit is contained in:
Julia Kreger 2023-07-27 10:01:31 -07:00
parent ab04ec8ce3
commit bb9b9001ad

View File

@ -2392,7 +2392,11 @@ class Connection(api.Connection):
query = add_identity_filter(query, allocation_id)
try:
ref = query.one()
# NOTE(TheJulia): We explicitly need to indicate we intend
# to update the record so we block until the other users of
# the row are free, such as the process to match the
# allocation to a node.
ref = query.with_for_update().one()
except NoResultFound:
raise exception.AllocationNotFound(allocation=allocation_id)