Oracle Sequence Transactionality

Мне нужно для конкретного бизнес-сценария установить поле на объекте (не на ПК) число из последовательности (последовательность должна быть числом от мин до макс.

Я определил последовательность следующим образом:

CREATE SEQUENCE MySequence
  MINVALUE 65536 
  MAXVALUE 4294967296 
  START WITH 65536
  INCREMENT BY 1
  CYCLE
  NOCACHE
  ORDER;

В Java-коде я извлекаю число из последовательности следующим образом:

select mySequence.nextval from dual

Мой вопрос:

Если я это называюselect mySequence.nextval from dual"В транзакции и в то же время в другой транзакции вызывается один и тот же метод (параллельные запросы), он уверен, что значения, возвращаемые последовательностью, отличаются?

Нельзя ли как-то прочитать незафиксированное значение из первой транзакции?

Например, я бы не использовал последовательность и простую таблицу, в которой я сам увеличивал бы последовательность, тогда транзакция 2 была бы в состоянии прочитать то же значение, если бы trasactinalitY было значением по умолчанию "READ COMMITTED".

4 ответа

Решение

Ответ - нет.

Oracle гарантирует, что числа, сгенерированные последовательностью, различны. Даже если выполняются параллельные запросы, окружение или откат RAC и коммиты являются смешанными.

Последовательности не имеет ничего общего с транзакциями.

Смотрите здесь документы:

Используйте оператор CREATE SEQUENCE, чтобы создать последовательность, которая является объектом базы данных, из которого несколько пользователей могут генерировать уникальные целые числа. Вы можете использовать последовательности для автоматической генерации значений первичного ключа.

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

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

Oracle гарантирует, что порядковые номера будут другими. Даже если ваша транзакция откатывается, последовательность "используется" и не переиздается в другой запрос.

Изменить: Добавление дополнительной информации после того, как требования о "нет пробелов" были заявлены в комментариях Cris

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

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

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

sequence.nextval никогда не возвращает одно и то же значение (до цикла) для одновременного запроса. Возможно, вам следует проверить следующий URL:

http://docs.oracle.com/cd/B19306_01/server.102/b14220/schema.htm

К сожалению, вы должны реализовать свое собственное колесо - последовательность транзакций. Это довольно просто - просто создайте таблицу, такую ​​как sequence_name varchar2, value, min_value number, max_value number, need_cycle char и возитесь "выберите значение в переменной из таблицы последовательности для ожидания обновления (или сейчас - это зависит от вашего сценария)". После этого введите обновление, установите значение = переменную из предыдущего шага + 1, где sequence_name = имя вашей последовательности и выполните оператор commit со стороны клиента. Вот и все.

Другие вопросы по тегам