Я работаю с приложением Rails 4, которому необходимо создать большое количество объектов в ответ на события из другой системы. Я часто встречаю ошибки ActiveRecord::RecordNotUnique
(вызванные PG::UniqueViolation
) в столбце первичного ключа, когда я вызываю create!
на одной из моих моделей.Rails: повторяется ActiveRecord :: RecordNotUnique при создании объектов с помощью Postgres?
я нашел другие ответы на SO, которые предлагают Спасая исключение и призывающие retry
:
begin
TableName.create!(data: 'here')
rescue ActiveRecord::RecordNotUnique => e
if e.message.include? '_pkey' # Only retry primary key violations
log.warn "Retrying creation: #{e}"
retry
else
raise
end
end
Хотя это, кажется, помогает, я все еще получаю тонн из ActiveRecord::RecordNotUnique
ошибок, для последовательных идентификаторов, которые уже существуют в базы данных (записи журнала сокращенные):
WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3067) already exists.
WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3068) already exists.
WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3069) already exists.
WARN -- Retrying creation: PG::UniqueViolation: DETAIL: Key (id)=(3070) already exists.
идентификаторы он пытается находятся в 3000-4000 диапазоне, несмотря на наличии более 90000 записей в таблице.
Почему ActiveRecord или PostgreSQL тратят столько времени на последовательное тестирование существующих идентификаторов?
Оригинальное исключение (упрощенная строка/удаленный запрос):
{
"exception": "ActiveRecord::RecordNotUnique",
"message": "PG::UniqueViolation: ERROR: duplicate key value violates unique constraint \"table_name_pkey\"\nDETAIL: Key (id)=(3023) already exists."
}
Любые мысли о том, как идентификаторы и последовательность могут выйти из синхронизации? Это случилось со мной тоже, и исправление прост, но я хотел бы знать, как могла возникнуть проблема изначально ... –
В моем случае последовательности вышли из синхронизации из-за импорта объемных данных, которые устанавливают идентификаторы напрямую, но не обновлял последовательности.* Возможно, это также может произойти, если одновременные процессы создают множество записей одновременно? – nitrogen