12 апр. 2012 г.

Опять двадцать пять...

...или почему задвоились объекты при переносе потоком.

Когда 3 апреля грохнулась база предприятия Б, мы восстановили архив на 30 марта. Так как часть информации из исходной базы данных могла быть прочитана, объекты за 1-2 апреля были сохранены в поток и загружены на новую базу. В результате, некоторые записи задвоились. Почему?

Как известно, при загрузке из потока система пытается найти объект по его РУИДу или с помощью запроса из метода CheckTheSameStatement. Последний определен только для узкого круга классов, так что вся надежда на РУИДы. Если РУИД загружаемого объекта не найден, то считается что такого объекта нет и создается новая запись.

Предположим, некоторая запись была создана 20 марта на рабочей еще базе простым пользователем. РУИДа у этой записи не будет, потому как он автоматически присваивается только в трех случаях:

  1. Если работа идет под учетной записью Administrator.
  2. В момент открытия диалогового окна Свойства объекта.
  3. В процессе сохранения объекта в поток.
Первый раз РУИД сформируется при сохранении в поток на поврежденной базе данных. Естественно, что поиск по этому РУИДу при загрузке из потока на базу данных из архива ничего не даст. Система примет загружаемую запись за новую и создаст дубликат.

Можно ли было избежать такого неприятного развития событий? Да. Так как архивная база является копией исходной по состоянию на 30 марта, все объекты в обеих базах, созданные до указанной даты, имеют одинаковые идентификаторы. Следовательно, если мы:

  1. Не меняли идентификатор базы данных, восстановленной из архива. (Заметим, что даже если идентификатор базы был изменен, ничего страшного не произойдет. Главное — обеспечить равенство идентификаторов двух баз до начала выполнения шагов 2 и 3.)
  2. В поврежденной базе создали вручную РУИДы для всех записей.
  3. В архивной базе создали вручную РУИДы для всех записей.
то, можно спокойно переносить объекты потоком без угрозы задвоения.

Принудительно создать РУИДы для всех записей в базе можно с помощью приведенного здесь запроса. Обратите внимание на использование оператора MERGE.

Комментариев нет:

Отправить комментарий