|
|
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
Leonid KudryavtsevВ OeBS нумераторы (в пределах года) сделаны на сиквенсах AFAIK. Многие жалуются, многие плюются, но кактус вполне съедобный. Вот, кстати, в OeBS из-за сиквенсов и пришлось подобную задачу автонумерации делать, т.к.: 1. По требованию клиента не должно быть пропусков (это-то как раз несложно, но см. п.2) 2. На форме, которую нужно было кастомизировать приходили эвенты WHEN-NEW-FORM-INSTANCE (где номер и подпихивался) и по срабатыванию нажатия кнопки Ок. Ничего внятного промежуточного, на что можно было бы повесить вызов в CUSTOM.pll, не приходило. Т.е. при стандартной кастомизации форма была _однопользовательской_, что, разумеется, было неприемлимо. Делается все это через автономные транзакции. 1. Создается табличка вида OrgID, cur_number, is_used (Y/N) 2. По срабатыванию WHEN-NEW-FORM-INSTANCE происходит вызов функции (F1) пакета, которая делает следующее: - делает вызов, в свою очередь, функции в автономной транзакции (F2), которая возвращает текущий номер - ставит блокировку на запись с выданными OrgID + cur_number, поменяв is_used с N на Y Ну а дальше ждем в этой транзакции что пользователю заблагорассудится. 3. Функция в автономной транзакции (F2) делает следующее - определяет есть ли записи для текущего OrgID (читай тип очереди для данной задачи), и если нет, то вставляет запись в табличку со значениями OrgID, 1, 'N' и возвращает OrgID + 1 в основную транзакцию. - если есть несколько записей со статусом использования 'Y' и без блокировок на них - удаляем все, кроме той, где максимальное значение cur_number для данного OrgID. - если записи уже есть, статус использования 'N', то возвращаем эту запись (я брал минимальную, но тут не принципиально) - это те записи где либо стухла основная сессия, либо пользователь решил не сохранять данные на форме. - если запись со статусом 'Y' уже есть, на ней нет блокировки (к этому моменту она уже одна такая для текущего OrgID), то увеличиваем cur_number на 1, статус is_used ставим в 'N' и возвращаем в основную транзакцию. - с записями, на которых стоят блокировки ничего не делаем. При данном подходе форма стала многопользовательской и промежуточные значения не терялись. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2018, 15:15 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
Да, ТС нужно добавить в табличку еще поле типа дата и, соответственно в функциях F1 и F2 добавится параметр с типом дата. По умолчанию trunc(sysdate), подозреваю. Но в принципе можно записываться и на будущую дату. Чистить табличку по желанию (хотя чего там чистить - слёзы по нынешним временам). ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2018, 15:29 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
witte, ТС-у не критичны пропуски. В твоем варианте возможна ситуация, когда клиент получающий номер получит более ранний чем клиент подошедший до него, не факт что это хорошо. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2018, 17:39 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
SkilledJuniorТС-у не критичны пропуски. Я описал более общую задачу с недопущением пропусков, причем акцентировал на этом внимание. SkilledJuniorВ твоем варианте возможна ситуация, когда клиент получающий номер получит более ранний чем клиент подошедший до него, не факт что это хорошо. Если нет нужды печатать неиспользованные номера, то проблема решается убиранием ровно одной строчки из описанного мной алгоритма и модификацией еще одной (причем вторая строчка уже по желанию). Легко понять каких двух. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2018, 19:55 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
witte Я описал более общую задачу с недопущением пропусков Ничего твоя борьба с ветряными мельницами не гарантирует. Да еще из твоего повествования хрен поймешь, что с коллизиями. Например, навставляли сессии несколько строк 1,N. Каждая вернула 1. И дальше что? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2018, 22:50 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
-2-witte Я описал более общую задачу с недопущением пропусков Ничего твоя борьба с ветряными мельницами не гарантирует. Да еще из твоего повествования хрен поймешь, что с коллизиями. Например, навставляли сессии несколько строк 1,N. Каждая вернула 1. И дальше что? О, капитан-нечитатель :-) Почитай внимательней, всё там гарантируется. Более того, работает уже более 10 лет без всяких там "конец дня" для такой тривиальщины. ЗЫ: Ты про автономную транзакцию и блокировки (надеюсь не надо говорить как это проверить?) прочитал? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2018, 23:41 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
-2-Например, навставляли сессии несколько строк 1,N. Каждая вернула 1. Вот чтобы не быть голословным, пример можешь привести, в соответствии с моим алгоритмом как это сделать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 05.09.2018, 23:47 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
witteЕсли нет нужды печатать неиспользованные номера, то проблема решается убиранием ровно одной строчки из описанного мной алгоритма и модификацией еще одной (причем вторая строчка уже по желанию). Легко понять каких двух. 21665609 ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.09.2018, 00:03 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
witte-2-Например, навставляли сессии несколько строк 1,N. Каждая вернула 1.Вот чтобы не быть голословным, пример можешь привести, в соответствии с моим алгоритмом как это сделать?Вызвать F2 в нескольких сессиях и действовать по первому пунктуwitte- определяет есть ли записи для текущего OrgID (читай тип очереди для данной задачи), и если нет, то вставляет запись в табличку со значениями OrgID, 1, 'N' и возвращает OrgID + 1 в основную транзакцию. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.09.2018, 07:56 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
-2-Вызвать F2 в нескольких сессиях и действовать по первому пункту Да, действительно упустил. Тогда первую запись нужно создавать ручками а не в F2. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.09.2018, 10:02 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
SkilledJunior, спасибо. Поизучаю автономные транзакции ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.09.2018, 11:21 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
witte, Теперь понятнее, спасибо :) ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.09.2018, 11:24 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
witte-2-Вызвать F2 в нескольких сессиях и действовать по первому пункту Да, действительно упустил. Тогда первую запись нужно создавать ручками а не в F2.Допустим есть одна запись 123Y. Выполняем одновременно:автор- если запись со статусом 'Y' уже есть, на ней нет блокировки (к этому моменту она уже одна такая для текущего OrgID), то увеличиваем cur_number на 1, статус is_used ставим в 'N' и возвращаем в основную транзакцию.Если "нет блокировки" это select for update skip locked, то вторая сессия получает отсутствие строк. Реакция не описана, если вставка новой записи, то к чему добавлять +1? Если for update без skip locked, то вторая повиснет до завершения первой. После чего получит 124N. Далее апдейт на 125N? Первая мастер-сессия может отказаться от номера 124 и останется дырка. Если же под "нет блокировки" понимается значение Y, то эта алгоритмическая тавтология приведет к дублированию значения, как и в случае наличия в данных N. Что же до "алгоритма" вообще, то он не гарантирует отсутствие дырок, а надеется на их дальнейшее переиспользование. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.09.2018, 11:50 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
witteТогда первую запись нужно создавать ручками а не в F2. Плохое решение, нормальное решение это использование семафора, в твоем случае в качестве семафора можно использовать блокировку строки таблицы в которой OrgID является первичным ключом. ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.09.2018, 17:13 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
SkilledJuniorwitteТогда первую запись нужно создавать ручками а не в F2. Плохое решение, нормальное решение это использование семафора, в твоем случае в качестве семафора можно использовать блокировку строки таблицы в которой OrgID является первичным ключом.А запись-семафор не нужно создавать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.09.2018, 18:04 |
|
||
|
Уникальный номер в течении дня
|
|||
|---|---|---|---|
|
#18+
-2-А запись-семафор не нужно создавать? Обычно ресурс уже существует в какой нибудь таблице до того как его начинают планировать, у witte например OrgID явно откуда то берется, т.е. уже существует, у Morra такой таблицы нет, поэтому приходится создавать такую таблицу и вставлять в нее запись, эта запись является метаданными приложения и должна быть включена в скрипт создания объектов БД для приложения. Если не использовать таблицу ресурсов, а сразу в таблицу планирования/счетчик номеров добавить по одной записи на каждую дату, то сколько записей добавлять? На год или на два? А через год что, приложение внезапно перестанет работать? ... |
|||
|
:
Нравится:
Не нравится:
|
|||
| 06.09.2018, 22:03 |
|
||
|
|

start [/forum/topic.php?fid=52&msg=39698562&tid=1883494]: |
0ms |
get settings: |
8ms |
get forum list: |
9ms |
check forum access: |
2ms |
check topic access: |
2ms |
track hit: |
200ms |
get topic data: |
8ms |
get forum data: |
2ms |
get page messages: |
51ms |
get tp. blocked users: |
1ms |
| others: | 206ms |
| total: | 489ms |

| 0 / 0 |
