Безопасный способ хранить генератор первичного ключа вне базы данных? - PullRequest
3 голосов
/ 22 февраля 2011

У нас есть приложение, которое хранит свои данные в SQL Server.Каждая таблица имеет первичный ключ bigint.Мы использовали их для генерации исключительно по требованию, т. Е. Когда вы вставляете новую строку, сначала вызывается для создания следующего идентификатора, а затем выполняется вставка.

Мы добавили поддержку для запуска в автономном режимеРежим: если ваше соединение не работает (или SQL Server не работает), он сохраняет данные в локальный файл, пока вы не вернетесь в оперативный режим, а затем синхронизирует все, что вы сделали с тех пор.

Это требовало возможностигенерировать идентификаторы на стороне клиента.Вместо того, чтобы запрашивать SQL для следующего 1 идентификатора, теперь он запрашивает следующие сто, тысячу или 10 000 идентификаторов, а затем сохраняет диапазон локально, поэтому ему не нужно запрашивать больше, пока эти 10000 не закончатся.На самом деле они получаются небольшими порциями, поэтому, когда 5000 заканчивается, у него все еще есть буфер 5000, и он может запросить еще 5000.

Проблема в том, что, как только это было запущено, мы началиполучение отчетов о нарушениях первичных ключей.Мы сохранили данные в реестре Windows, в HKEY_CURRENT_USER (единственное место в реестре, на которое гарантированно может писать пользователь).Поэтому после некоторого исследования мы обнаружили, что HKEY_CURRENT_USER является частью перемещаемого профиля, поэтому возможно, что идентификаторы могут быть перезаписаны старой версией.Особенно, если пользователь подключается к нескольким компьютерам в сети одновременно.

Поэтому мы переписали часть, которая генерирует идентификаторы для чтения / записи файла из пользовательского каталога «Локальные настройки».Конечно, это не должно быть перезаписано старой версией.Но даже сейчас я все еще вижу случайные нарушения первичных ключей.Единственное, что мы можем сделать в этом случае, это удалить любые ключи в файле, выгнать пользователя из приложения и не пускать его обратно, пока они не получат новые диапазоны идентификаторов.

Но если "LocalНастройки "не безопасно, что бы?Есть ли где-нибудь, где вы можете сохранить постоянное значение на компьютере, которое гарантированно не будет отменено до старой версии?Может кто-нибудь объяснить, почему «Локальные настройки» не соответствуют этим критериям?

Я рассмотрел решение, похожее на GUID, но оно само по себе имеет проблемы.

Ответы [ 3 ]

5 голосов
/ 22 февраля 2011

в распределенной среде, как ваша, лучше всего использовать GUID

1 голос
/ 22 февраля 2011

Нужно ли использовать тот же ключ при локальном сохранении данных, который вы используете при синхронизации с базой данных?

Мне бы очень хотелось использовать GUID при локальном сохранении данных, а затемгенерировать реальный ключ, когда вы фактически записываете данные в базу данных.Или сохраняйте данные локально, начиная со значения 1, а затем генерируйте реальные ключи, когда вы фактически записываете данные в базу данных.

0 голосов
/ 22 февраля 2011

Настройка IDENTITY (http://www.simple -talk.com / sql / t-sql-программирования / identity-columns / ) в первичном ключе bigint, чтобы SQL Server автоматически генерировал значения.

Когда ваше приложение находится в автономном режиме, ожидающие изменения остаются локальными.Когда он возвращается в оперативный режим, вы отправляете свои обновления (включая новые записи), и SQL Server вставляет их и автоматически назначает первичный ключ, поскольку у вас есть настройка IDENTITY.

Если вам нужно знать, какое значение ключа было сгенерировано/ используется после вставки, вы можете использовать свойство @@ IDENTITY (http://msdn.microsoft.com/en-us/library/aa933167%28v=sql.80%29.aspx)

...