Уникальный числовой инкрементный идентификатор

StackOverflow https://stackoverflow.com/questions/643267

  •  22-07-2019
  •  | 
  •  

Вопрос

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

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

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

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

Это было полезно?

Решение

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

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

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

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

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

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

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

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

Другие советы

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

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

  

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

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

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

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

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

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

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

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

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

Лицензировано под: CC-BY-SA с атрибуция
Не связан с StackOverflow
scroll top