Open aaronskiba opened 1 week ago
There are several bugs that stem from these duplicate entries:
ActiveRecord::RecordInvalid: Validation failed: Question must be unique
is raised)ActiveRecord::RecordInvalid Exception: Validation failed: Question must be unique
)
Please complete the following fields as applicable:
What version of the DMPRoadmap code are you running? (e.g. v2.2.0)
4.1.1+portage-4.1.0-uat-4
4.1.1+portage-4.1.0-alpha-3
Expected behaviour: The following code within
app/models/answer.rb
is meant to prevent duplicate (plan_id, question_id) entries from existing within the answers table.Actual behaviour: The following SQL query was performed on a recent database dump from the production environment. It reveals that there are in fact duplicate (plan_id, question_id) entries existing within the answers table.
Diagnosis
There are 11 (22/2) answers with "duplicates" in the answers table. So only 0.00016% (11/67327) of the answers entries are affected.
This table illustrates how close the created_at values are between the answers and their duplicates (max = 0.014105 seconds).
We can see there is a very small percentage of duplicates, and the created_at difference is very small between the answers and their corresponding duplicates. Given all of this, it seems quite possible that we're sometimes encountering a race condition which causes the question uniqueness validation check to sometimes "fail". When two records are being saved nearly simultaneously, the validation check might pass for both before either is committed to the database, leading to the insertion of duplicate entries.
This seems even more likely when we factor in the 'auto-save' feature being used for answers. If a manual save was executed and an auto-save was triggered at nearly the same moment, then the aforementioned scenario could occur.
Perhaps a migration should be created to enforce the uniqueness constraint at the db level? (Along with the migration, we would also need a script to delete one out of every pair of duplicate answers currently existing within the answers table.)