Rails: нарушение ограничения при создании, но не при обновлении - PullRequest
3 голосов
/ 13 апреля 2010

Примечание: Это "рельсовая" (и более краткая) версия этого вопроса , которая становилась немного длиннее.

Я получаю поведение Rails на рабочем сервере, которое не могу воспроизвести на сервере разработки. Кодовые базы идентичны, за исключением учетных данных и параметров кэширования, и обе они работают на базах данных Oracle 10g с идентичной схемой (но с разными данными).

Приложение My Rails содержит модель пользователя, которая имеет регистрацию has_one; В свою очередь, регистрация has_and_belongs_to_many company_ownerships осуществляется через таблицу registration_ownerships. После регистрации пользователи заполняют данные, относящиеся ко всем трем моделям, включая серию флажков, указывающих, что registration_ownerships может применяться к их учетной записи.

На сервере dev процесс регистрации проходит без проблем, независимо от того, какие данные вводятся. Однако в производственной среде, если пользователи отмечают какое-либо из полей собственности компании перед отправкой своей регистрации, Oracle жалуется на нарушение ограничения для первичного ключа таблицы company_ownerships (который представляет собой ключ из двух полей на основе company_ownership_id и registration_id) и пользователей. получить стандартный экран ошибок Rails 500. В каждом случае я проверял, что в рабочей базе данных нет конфликтующих записей в этих двух полях, поэтому я не знаю, почему ограничение нарушается.

Чтобы еще больше сбить с толку, если пользователь регистрируется без указания каких-либо владельцев, а затем возвращается и изменяет свою учетную запись, чтобы отразить данные о владельцах (что делается через тот же интерфейс), приложение успешно выполняет его запрос, и Oracle хорошо вела себя (это касается как производства, так и разработки).

Я провел последние пару дней, пытаясь выяснить, что может быть причиной этой проблемы, и я дошел до конца. Любой совет будет принята с благодарностью!

ОБНОВЛЕНИЕ 4/15/10: Я только что заметил кое-что, что могло бы быть полезным. Я попытался зарегистрировать идентичные учетные записи в dev и production и намеренно оставил поле «телефон» пустым, которое является обязательным. На dev я получил следующее сообщение:

1 ошибка не позволила сохранить эту регистрацию

Были проблемы со следующими полями:

  • Телефон не может быть пустым

Тем не менее, на производстве я получаю это:

2 ошибки не позволили сохранить эту регистрацию

Были проблемы со следующими полями:

  • Телефон не может быть пустым
  • Телефон не может быть пустым

Я предполагаю, что это напрямую связано с нарушением ограничения на производство - возможно, как часть фиксации, поле вставляется один раз, а затем вставляется снова, но нарушает ограничение во второй раз, а затем откатывает всю транзакцию , удалив все доказательства первоначальной вставки. Любые идеи о том, что может быть причиной такого поведения, на стороне Rails или на стороне Oracle?

Ответы [ 2 ]

1 голос
/ 14 апреля 2010

Во-первых, проверьте, подключается ли приложение к базе данных, к которой, как вы думаете, оно подключается.

Во-вторых, проверьте типы данных, включая числовую точность. Например, в следующем примере десятичные разряды молча усекаются, поэтому вторая вставка завершается неудачно с дублирующим ключом

create table test_pk (pk_1 number(3,0), pk_2 number(3,0), val varchar2(20));
alter table test_pk add constraint test_pk_pk primary key (pk_1, pk_2);
insert into test_pk values (10.1, 10.1, 'test 10.1');
insert into test_pk values (10.2, 10.2, 'test 10.2');

В худшем случае отключите ограничение, попробуйте выполнить операцию и снова включите ограничение. Это скажет вам, действительно ли поступают какие-то повторяющиеся данные. Может быть какое-то странное состояние гонки, происходящее с пулами соединений и не немедленными операциями (например, вставки в соединение a, удаления в соединение b, вставки в соединение a перед соединением b совершил.)

0 голосов
/ 20 апреля 2010

Как оказалось, в каталоге была резервная копия модели "регистрации"; хотя у него было другое имя ("registrations_2349871.rb" или что-то в этом роде), Rails дважды запускал всю функциональность модели (сохранение, проверка и т. д.), отсюда и нарушение ключевого ограничения! Я никогда не видел такого поведения раньше. Удаление мошеннического файла решило проблему.

...