Project

Profile

Help

Issue #5982

closed

Race condition in RepositoryVersion.new_version()

Added by osapryki almost 5 years ago. Updated about 4 years ago.

Status:
CLOSED - WORKSFORME
Priority:
Normal
Assignee:
-
Category:
-
Sprint/Milestone:
-
Start date:
Due date:
Estimated time:
Severity:
2. Medium
Version:
Platform Release:
OS:
Triaged:
Yes
Groomed:
No
Sprint Candidate:
No
Tags:
Sprint:
Quarter:

Description

If `RepositoryVersion.new_version` is executed at the same time in two parallel transactions, one of transactions may fail with unique constraint error:

duplicate key value violates unique constraint "pulp_app_repositoryversion_repository_id_number_07cb5788_uniq" DETAIL: Key (repository_id, number)=(1, 735) already exists.

This is caused because of race condition possible in `RepositoryVersion.new_version()` call:

SELECT last_version FROM pulp_app_repository WHERE id = 1
 last_version
--------------
          21

TRANSACTION 1       TRANSACTION 2
=============       =============
BEGIN;
-----------------------------------------------------------
                    BEGIN;
-----------------------------------------------------------
INSERT INTO pulp_app_repositoryversion
(repository_id, number) VALUES (1, 22)
# NOTE: number = int(self.last_version) + 1;
-----------------------------------------------------------
UPDATE pulp_app_repository
SET last_version = 22;
-----------------------------------------------------------
                    INSERT INTO pulp_app_repositoryversion
                    (repository_id, number) VALUES (1, 22)
                    # NOTE: number = int(self.last_version) + 1;
-----------------------------------------------------------
                    UPDATE pulp_app_repository
                    SET last_version = 22;
-----------------------------------------------------------
COMMIT;
# NOTE: OK
-----------------------------------------------------------
                    COMMIT;
                    # NOTE: uplicate key value violates unique
                    # constraint
-----------------------------------------------------------

Solution:

You should lock repository record to perform `last_version` increment and update (e.g. do SELECT FOR UPDATE before incrementing last_version counter and creating a new version).

Also available in: Atom PDF