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


Можно ли заблокировать последовательность Oracle, чтобы любая сессия, пытающаяся использовать nextval, блокировалась до тех пор, пока я не закончу со своим сценарием?

Я объясню, что я делаю, если есть другой способ. Я готовлю схему для выполнения двунаправленной репликации с потоками. Я хочу убедиться, что все последовательности первичных ключей дают уникальные значения. Я делаю это, увеличивая последовательность на 1, пока последняя цифра не станет 1, а затем изменяю приращение на 100. На другом сервере я делаю то же самое, пока последняя цифра-2. Таким образом, сервер 1 всегда производит первичные ключи XXXXX01 и сервер 2 XXXXX02.

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

4   2   2011-04-09 03:36:59

4 ответа:

Нет, вы не можете заблокировать последовательность. Вы можете попытаться воссоздать последовательности в требуемом состоянии. Это вызовет проблему на короткое время.

Самым простым решением (на мой взгляд) является использование нечетных чисел для сервера 1 и четных чисел для сервера 2. Это также устраняет необходимость в сериализации.

create sequence server1_seq increment by 2 start with 1;
create sequence server2_seq increment by 2 start with 2;

Это дало бы ряд значений, таких как:

Server 1  Server 2
--------  --------
   1          2
   3          4
   5          6 
   7          8
   9         10

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

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

Мне лично нравится идея использования отдельных непересекающихся последовательностей, как предложил Роннис.

Еще один вариант, который следует рассмотреть, - это составной первичный ключ.

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

  2. Если вы не можете добавить столбец, вы можете вместо этого изменить тип данных столбца на VARCHAR2 и установить его в качестве составного; например, на сервере 1 Вы будет связывать '1-' со значением последовательности, например '1-103450', поэтому не будет конфликтовать с' 2-103450', генерируемым на сервере 2.

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

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

REVOKE SELECT ON mysequence FROM username;

Примечание: это не блокировка как таковая; вместо ожидания они получат ошибку Oracle (недопустимый идентификатор, я думаю).