Oracle (МН / SQL): ОБНОВЛЕНИЕ ВОЗВРАЩАЕТСЯ параллельный?

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

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

Я создаю записи (давайте назовем их объектами), которые имеют дорогое (bucket_id, цифра = счетчик).

Я должен гарантировать, что bucket_id / цифровая комбинация уникальна (настолько использующая последовательность, поскольку дорогой не решит мою проблему).

Создания строк не происходит в pl/sql, таким образом, я должен требовать числа (btw: это не против требований, чтобы иметь разрывы).

Мое решение было:

   UPDATE bucket
      SET counter = counter + 1
    WHERE id = param_id
RETURNING counter INTO num_forprikey;

Могут быть созданы МН возвраты / возвраты SQL var_num_forprikey так запись объекта.

Вопрос:

Я буду всегда получать уникальный num_forprikey, даже если пользователь одновременно попросит новые объекты в блоке?

5
задан OMG Ponies 28 May 2010 в 16:27
поделиться

4 ответа

Всегда ли я получу уникальный num_forprikey даже если пользователь одновременно запрашивает новые предметы в ведре?

Да, по крайней мере, до определенной степени. Первый пользователь, выпустивший это обновление, получает блокировку строки. Таким образом, ни один другой пользователь не может успешно выполнить тот же оператор, пока пользователь numero uno не зафиксирует (или не откатится). Так что уникальность гарантирована.

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

7
ответ дан 14 December 2019 в 01:02
поделиться

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

http://www.orafaq.com/forum/t/83382/0/ Преимущество последовательностей (и они могут создаваться динамически, если вы можно указать отсутствие кэширования и гарантийный заказ)

0
ответ дан 14 December 2019 в 01:02
поделиться

I кажется, припоминаю эту проблему, когда много лет назад работал над базой данных INGRES. В то время не было последовательностей, поэтому лучшие умы INGRES приложили много усилий для поиска лучшего решения масштабирования для этой проблемы. Мне посчастливилось работать вместе с ними, так что даже при том, что мой разум прискорбно меньше, чем у любого из них, близость = остаточный аффект, и я что-то сохранил. Это была одна из вещей. Дай мне посмотреть, могу ли я вспомнить.

1) for each counter you need row in a work table.
2) each time you need a number
  a) lock the row
  b) update it
  c) get its new value (you use returning for this which I avoid like the plague)
  d) commit the update to release your lock on the row

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

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

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

1) последовательность обновления / выбора / фиксации делает все возможное, чтобы сократить время, в течение которого строка KEY заблокирована, но она все еще не равна нулю. При большой нагрузке вы будете сериализованы и в конечном итоге будете ограничены.

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

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

Но если это требует ваш заказчик, что вы можете сделать правильно?

Удачи. Я не проверял код на наличие синтаксических ошибок, оставляю это вам.

create or replace function get_next_key (key_name_p in varchar2) return number is
   pragma autonomous_transaction;
   kev_v number;
begin

   update key_table set key = key + 1 where key_name = key_name_p;

   select key_name into key_name_v from key_name where key_name = key_name_p;

   commit;

   return (key_v);

end;
/
show errors
1
ответ дан 14 December 2019 в 01:02
поделиться

Вы все еще можете использовать последовательности, просто используйте аналитическую функцию row_number(), чтобы порадовать своих пользователей. Более подробно я описал это здесь: http://rwijk.blogspot.com/2008/01/sequence-within-parent.html

С уважением, Роб.

1
ответ дан 14 December 2019 в 01:02
поделиться
Другие вопросы по тегам:

Похожие вопросы: