FIX: Race condition in draft sequence updates (#12299)

This was causing RecordNotUnique exceptions
This commit is contained in:
Daniel Waterworth 2021-03-05 13:40:00 -06:00 committed by GitHub
parent 5d95b68727
commit fae2fc0b5e
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
1 changed files with 15 additions and 8 deletions

View File

@ -9,14 +9,21 @@ class DraftSequence < ActiveRecord::Base
return 0 if !User.human_user_id?(user_id) return 0 if !User.human_user_id?(user_id)
h = { user_id: user_id, draft_key: key } sequence =
c = DraftSequence.find_by(h) DB.query_single(<<~SQL, user_id: user_id, draft_key: key).first
c ||= DraftSequence.new(h) INSERT INTO draft_sequences (user_id, draft_key, sequence)
c.sequence ||= 0 VALUES (:user_id, :draft_key, 1)
c.sequence += 1 ON CONFLICT (user_id, draft_key) DO
c.save! UPDATE
DB.exec("DELETE FROM drafts WHERE user_id = :user_id AND draft_key = :draft_key AND sequence < :sequence", draft_key: key, user_id: user_id, sequence: c.sequence) SET sequence = draft_sequences.sequence + 1
c.sequence WHERE draft_sequences.user_id = :user_id
AND draft_sequences.draft_key = :draft_key
RETURNING sequence
SQL
DB.exec("DELETE FROM drafts WHERE user_id = :user_id AND draft_key = :draft_key AND sequence < :sequence", draft_key: key, user_id: user_id, sequence: sequence)
sequence
end end
def self.current(user, key) def self.current(user, key)