Уникальный, числовой, инкрементный идентификатор - PullRequest
3 голосов
/ 13 марта 2009

Мне нужно генерировать уникальные, инкрементные числовые идентификаторы транзакций для каждого запроса, который я делаю к определенному XML RPC. Эти числа должны быть уникальными только для моего домена, но будут сгенерированы на нескольких машинах.

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

Любые идеи будут оценены.

Изменить: Что делать, если идентификатор каждой транзакции просто должен быть больше, чем предыдущий запрос?

Ответы [ 7 ]

4 голосов
/ 13 марта 2009

Если вы собираетесь использовать это из сотен потоков, работающих на нескольких машинах и требующих инкрементного идентификатора, вам потребуется централизованное место для хранения и блокировки последнего сгенерированного идентификационного номера. Это не обязательно должно быть в базе данных, но это будет наиболее распространенный вариант. Центральный сервер, который ничего не делал, кроме обслуживающих идентификаторов, мог бы обеспечивать такую ​​же функциональность, но, вероятно, не справлялся с целью его распространения.

Если они должны быть инкрементными, любая форма метки времени не будет гарантированно уникальной.

Если вам не нужно, чтобы они были инкрементными, GUID работал бы. Потенциально выполнение некоторого типа слияния временной метки + аппаратный идентификатор в каждой системе может дать уникальные идентификаторы, но часть идентификационного номера не обязательно будет уникальной.

Не могли бы вы использовать пару идентификаторов оборудования + дополнительные временные метки? Это приведет к тому, что идентификаторы каждого конкретного компьютера будут инкрементными, но не обязательно будут уникальными для всего домена.

---- РЕДАКТИРОВАТЬ -----

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

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

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

1 голос
/ 13 марта 2009

Это очень сложная проблема, особенно если вы не хотите создавать узкое место в производительности. Вы говорите, что идентификаторы должны быть «инкрементными» и «числовыми» - это конкретное бизнес-ограничение или такое, которое существует для какой-то другой цели?

Если в этом нет необходимости, вы можете использовать UUID, для которых большинство распространенных платформ имеют библиотеки. Они позволяют вам генерировать много (миллионы!) Идентификаторов за очень короткие промежутки времени и чувствовать себя комфортно без коллизий. Соответствующая статья о википедии утверждает:

Другими словами, только после генерации 1 миллиард UUID каждую секунду для ближайшие 100 лет вероятность создание только одного дубликата будет около 50%.

0 голосов
/ 13 марта 2009

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

Это сделает вашу систему центральным источником идентификаторов, и при этом все равно не нужно будет обращаться к базе данных для каждого идентификатора.

0 голосов
/ 13 марта 2009

Я с толпой GUID, но если это невозможно, не могли бы вы рассмотреть возможность использования db4o или SQL Lite для базы данных с большим весом?

0 голосов
/ 13 марта 2009

Google для генераторов GUID для любого языка, который вы ищете, а затем преобразуйте его в число, если вам действительно нужно, чтобы он был числовым. Это не постепенно.

Или пусть каждый поток «резервирует» тысячу (или миллион, или миллиард) идентификаторов транзакций и выдает их по одному за раз, и «резервирует» следующую связку, когда она заканчивается. Все еще не очень инкрементно.

0 голосов
/ 13 марта 2009

Если вы ориентируетесь на платформу Windows, вы пробовали Interlocked API ?

0 голосов
/ 13 марта 2009

Если вы удалите «добавочный» из своих требований, вы можете использовать GUID .

Я не понимаю, как вы можете реализовать инкрементный в нескольких процессах без каких-либо общих данных.

...