2012-03-10 5 views
6

Учитывая, что SQL Azure Federations не поддерживает свойство IDENTITY или SEQUENCE, что было бы эффективным способом генерации последовательных чисел при вставке записей?Эффективный способ генерации последовательных чисел в SQL Azure Federations

Например, дана таблица этих колонок:

CREATE TABLE [dbo].[Orders] (
    [TenantId] [uniqueidentifier] NOT NULL, 
    [OrderId] [uniqueidentifier] NOT NULL, 
    [OrderNumber] [int] NOT NULL 
    CONSTRAINT [PK_Orders] PRIMARY KEY CLUSTERED (
     [TenantId] ASC, 
     [OrderId] ASC 
    ) 
) FEDERATED ON ([FederationKey] = [TenantId]) 

для каждого заказа, вставленный для данного арендатора, OrderId должен быть увеличен. Например, для палатки A OrderId будет 1, 2, 3 ... и для арендатора B OrderId также будет 1, 2, 3 ... в независимой последовательности. В идеале не должно быть пробелов.

TenantId и OrderId являются компонентами первичного ключа. Их значения задаются приложением, и они не связаны с проблемой генерации последовательностей; только OrderId имеет порядковый номер с бизнес-значением. Кроме того, TenantId является ключом распределения федерации.

This MSDN Blog article описывает в варианте 1 подход к тому, чтобы таблица содержала последовательности и использовала хранимую процедуру в отдельной транзакции для увеличения последовательностей. У каждого арендатора была бы запись на этой таблице, содержащая последнее использованное значение последовательности.

Будет ли это оптимальным подходом к рассмотрению возможности масштабирования, конкуренции, блокировки ресурсов? Любые другие полезные трюки, учитывая ограничения SQL Azure Federations?

ответ

2

Вот еще 2 идеи.

Подход должен состоять в том, чтобы иметь отдельный процесс обновления этого поля, чтобы сделать это асинхронным, если это возможно для вашего бизнес-сценария. Для этого подхода необходимо, чтобы поле OrderNumber принимало значения NULL. Чтобы узнать, какой заказ пришел первым, чтобы он получил правильный OrderNumber, я бы также добавил поле InsertedDate. Асинхронная обработка становится более сложной, если у вас есть несколько рабочих ролей, выполняющих эту обязанность для избыточности, и в этом случае вам нужно будет, чтобы каждый процесс присваивал себе записи, над которыми он работает (так что вам также нужно поле OwnedBy), добавьте проверку параллелизма во время UPDATE, чтобы гарантировать, что каждый процесс выполняется на его собственных записях, и истечет срок назначения записей (так что вам также нужно поле AssignedOn), если процесс выйдет из строя, чтобы он не оставил сирот. Не совсем тривиально ...

И тогда у вас есть подход бедного человека ... который, когда звезды выравниваются достаточно хорошо, может быть всем, что вам нужно. Если вы хотите иметь оптимистический подход к параллелизму, попробуйте использовать следующий номер во время вставки (сначала выберите номер заказа MAX для данного TenantId и OrderId), а затем выполните команду «Вставить». Если вставка терпит неудачу (потому что вы добавили уникальный индекс в TenantId, OrderNumber для этой цели), просто добавьте 1 в OrderNumber. Реальная проблема здесь - частота повторных попыток и вероятность того, что этот подход не удастся. Если у вас есть относительно оптимизированный бизнес-процесс, это может фактически не потерпеть неудачу; если, однако, у вас есть заказы, добавленные постоянно с нескольких путей, это может быть неприемлемым подходом.

+0

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

2

не уверен, сколько усилий потребуется, чтобы соответствовать вашему сценарию, но посмотрите на это, а также и посмотреть, если вы можете настроить его: SnowMaker – a unique id generator for Azure (or any other cloud hosting environment)

+1

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

+0

Вы по-прежнему рекомендуем использовать это? –