mirror of
https://github.com/discourse/discourse.git
synced 2025-03-01 00:27:58 +08:00

This is a backport of 84e13e9. We caught it in logs, race condition led to this error: ActiveRecord::RecordNotUnique (PG::UniqueViolation: ERROR: duplicate key value violates unique constraint "user_statuses_pkey" DETAIL: Key (user_id)=(15) already exists.) The reason the problem happened was that we were checking if a user has status and if not inserting status: if user_status ... else self.user_status = UserStatus.create!(status) end The problem is that it's possible that another request will insert status just after we check if status exists and just before our request call `UserStatus.create!(status)`. Using `upsert` fixes the problem because under the hood `upsert` generates the only SQL request that uses "INSERT ... ON CONFLICT DO UPDATE". So we do everything in one SQL query, and that query takes care of resolving possible conflicts.