2010-02-16 2 views
0

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

Примером может быть несколько предприятий, планирующих несколько Рабочих мест; Job.Number должен быть уникальным в бизнесе.

Поэтому я в основном должен убедиться, что одновременные операции создания задания не производят задания с тем же номером.

В настоящее время я вижу только один способ осуществить это (в postresql):

блокировать таблицу с типом самозажимного замка, скажем, «SHARE UPDATE ЭКСКЛЮЗИВ», так что все остальные операции этого типа должны очереди и ожидания, тем самым гарантируя, что функция MAX() всегда возвращает уникальное значение.

Однако в этом решении существует огромный недостаток - он по существу создает узкое место для всех операций INSERT в таблице рабочих мест.

Я не думаю, что я могу использовать Postgreql последовательности, потому что:

  1. Я не хочу, чтобы создать новую последовательность для каждого нового бизнеса
  2. Это может иметь разрывы

бы вы предлагаете какие-либо другие способы решения этой проблемы?

+0

Хорошо, как насчет другого подхода, который я объяснил в своем ответе ниже? Даже если Postgres не позволяет вам блокировать одну запись для чтения запросов, вы можете использовать трюки, подобные Optimistic Locking, чтобы убедиться, что только один процесс получает возможность увеличить номер процесса, а остальные терпят неудачу и должны повторить попытку (после того, сначала прочитайте текущий максимум). –

+0

Спасибо, мне еще предстоит измерить производительность как оптимистических/пессимистических блокировок, так и посмотреть, где находится точка пересечения в количестве транзакций в минуту с точки зрения производительности. – Art

ответ

1

Прежде всего, если все, что вам нужно, это отличное число, почему бы вам не использовать последовательность для его создания?

Если общая последовательность не подходит, поскольку генерирует «пробелы» (то есть задания № 1 могут быть пронумерованы 1,2,5,6,23, а задания № 2 могут получить 4,7,8,20 и так далее) или по какой-либо причине, почему вы не построить таблицу «счетчиков заданий»:

> Business ID | Job Counter 
---------------------------- 
> Business #1 | 23 
> Business #2 | 3 
> Business #3 | 11 
> Business #4 | 76 

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

0

Как насчет заявления SELECT * FOR UPDATE?

Также я хочу заметить, что CREATE SEQUENCE имеет параметр «CACHE», поэтому он может работать быстрее, если вы беспокоитесь о некоторых пробелах.

+0

Выбор * для обновления эквивалентен блокировке таблицы. И кеш в последовательности не обязательно поможет с пробелами. –

Смежные вопросы