Кажется, я вспоминаю эту проблему из многих лет назад, работая над всеми базами данных INGRES. В те дни не было никаких последовательностей, поэтому было затрачено много усилий на то, чтобы найти лучшее решение для масштабирования для этой проблемы с помощью лучших идей INGRES того дня. Мне посчастливилось работать вместе с ними так, что, хотя мой разум жалко меньше любого из них, proxmity = остаточный аффект, и я что-то сохранил. Это была одна из вещей. Позвольте мне посмотреть, помню ли я.
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
Я так думаю, но я не могу найти документацию об этом !! – Jaap