Fix interleaved repo delete with RAC via a transaction
The RepositoryActionCount table can have entries added while a repository deletion is in progress. We now perform the repository deletion under a transaction and explicitly test for RAC entries in the deletion unit test (which doesn't test interleaving, but it was missing this check). Fixes #494
This commit is contained in:
parent
d6f4e0c7b2
commit
30379a2dd8
3 changed files with 36 additions and 13 deletions
|
@ -119,6 +119,7 @@ db = Proxy()
|
|||
read_slave = Proxy()
|
||||
db_random_func = CallableProxy()
|
||||
db_for_update = CallableProxy()
|
||||
db_transaction = CallableProxy()
|
||||
|
||||
|
||||
def validate_database_url(url, db_kwargs, connect_timeout=5):
|
||||
|
@ -164,6 +165,10 @@ def configure(config_object):
|
|||
if read_slave_uri is not None:
|
||||
read_slave.initialize(_db_from_url(read_slave_uri, db_kwargs))
|
||||
|
||||
def _db_transaction():
|
||||
return config_object['DB_TRANSACTION_FACTORY'](db)
|
||||
|
||||
db_transaction.initialize(_db_transaction)
|
||||
|
||||
def random_string_generator(length=16):
|
||||
def random_string():
|
||||
|
@ -373,14 +378,15 @@ class Repository(BaseModel):
|
|||
return sorted_models.index(cmp_fk.model_class.__name__)
|
||||
filtered_ops.sort(key=sorted_model_key)
|
||||
|
||||
for query, fk in filtered_ops:
|
||||
model = fk.model_class
|
||||
if fk.null and not delete_nullable:
|
||||
model.update(**{fk.name: None}).where(query).execute()
|
||||
else:
|
||||
model.delete().where(query).execute()
|
||||
with db_transaction():
|
||||
for query, fk in filtered_ops:
|
||||
model = fk.model_class
|
||||
if fk.null and not delete_nullable:
|
||||
model.update(**{fk.name: None}).where(query).execute()
|
||||
else:
|
||||
model.delete().where(query).execute()
|
||||
|
||||
return self.delete().where(self._pk_expr()).execute()
|
||||
return self.delete().where(self._pk_expr()).execute()
|
||||
|
||||
class Star(BaseModel):
|
||||
user = ForeignKeyField(User, index=True)
|
||||
|
|
Reference in a new issue