|
Генератор
|
|||
---|---|---|---|
#18+
Добрый день! Помогите пожалуйста решить такую проблему: выполняется хранимая процедура, производящая insert в таблицу, в режиме явно запущенной транзакции.Для этой таблицы определен триггер after insert, который устанавливает новое значение генератора на +1. Но при rollback действие процедуры отменяется, а триггера - нет. А мне необходимо, чтобы при rollback значение генератора устанавливалось в начальное (до транзакции). Можно ли это сделать в многопользовательской системе и как эта операция отразится для других пользователей? Использую Delphi 5, InterBase 5.5 Спасибо за помощь. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2002, 13:00 |
|
Генератор
|
|||
---|---|---|---|
#18+
Нельзя, в этом идея генераторов, что раз выданное значение больше не повторяется. Поэтому и достигается уникальность. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2002, 16:41 |
|
Генератор
|
|||
---|---|---|---|
#18+
1. А если мне при rollback выполнить процедуру, которая изменяет значение генератора на -1. 2. Или перед выполнением процедуры запомнить текущее значение генератора и при rollback изменить значение генератора, а транзакцию запустить, заблокировав таблицу для inserta. 3.Или вообще отказаться от генератора и использовать для получения следующего по порядку номера запрос : Select max(nzakaz) from zakaz и к этому значению + 1. Какой из возможных вариантов будет правильным? А может у кого-то есть еще другие предложения? Спасибо за совет. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2002, 17:11 |
|
Генератор
|
|||
---|---|---|---|
#18+
1. Пока твоя транзакция что-то там будет делать, другие пользователи тоже могут ее запустить и еще более увеличат значение генератора, так что твой "-1", как минимум, сможет привести к тому, что генератор будет несколько раз принимать одни и те же значения. 2.Если твоя транзакция короткая, то вместо генератора создай "паразитную" таблицу (например, table1) с единственным числовым полем (integer) и стартуй транзакцию так: SET TRANSACTION READ WRITE NO WAIT SNAPSHOT TABLE STABILITY RESERVING table1 FOR PROTECTED WRITE. При успехе этого оператора таблица table1 окажется заблокированной от ЗАПИСИ со стороны других user'ов, и ты сможешь прочесть значение ее поля и увеличить его на 1 (а затем чего-то делать полезное), а при ROLLBACK'e - уменьшить на 1 (естессно, непосредственно ПЕРЕД ROLLBACK'ом) и вернуться на прежнее значение. 3. Если транзакция "длинная" по времени, то таблицу блокировать нельзя, тогда можно всё равно увеличивать в ней счетчик на 1, но обязательно запомнить его НОВОЕ значение и перед ROLLBACK'ом проверить, ОСТАЛОСЬ ли оно прежним (т.е. не увеличил ли его еще кто-нить). Тогда делай отдельно транзакцию с блокировкой table1, увеличивай там значение поля на 1 и запоминай его, затем сразу "отпусти" table1 (COMMIT). Потом делай что-то в основной транзакции, а перед ее ROLLBACK'ом - снова читай table1 и проверь, осталось ли значение счетчика прежним. Не уверен на 100%, правда, что это будет работать правильно. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2002, 18:36 |
|
Генератор
|
|||
---|---|---|---|
#18+
Зачем after Insert? Если речь идет о простой генерации уникальных значений ПК, а не об упорядочении ПК, то Я обычно делаю так: CREATE TRIGGER TABLE1_TRIG_BI FOR TABLE1 ACTIVE BEFORE INSERT POSITION 0 AS BEGIN NEW.ID_TABLE1 = GEN_ID(GEN_ID_TABLE1,1); END Значение поля в этом случае будет всегда уникальным, однако если потом будет RollBack, то значения просто будут идти не попорядку. Если задача иного рода, т.е. не генерация ПК (напр., чтоб все значения поля шли по порядку), то для этой цели лучше написать хп, которая все это будет отслеживать. ... |
|||
:
Нравится:
Не нравится:
|
|||
25.12.2002, 19:47 |
|
Генератор
|
|||
---|---|---|---|
#18+
Мне надо чтобы все значения поля шли по порядку, а не только чтоб были уникальны. В том то все и дело. Получается, хранить в генераторе значение- отпадает. Использовать паразитную таблицу - тоже не катит т.к. такого рода поле мне нужно в 5 таблицах. Остается третий вариант. Его и попробуем, потом поделюсь впечатлениями. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2002, 11:27 |
|
Генератор
|
|||
---|---|---|---|
#18+
Привет! Вопрос о значениях, идущих по порядку давно и многократно обсуждался. Общий выод - прежде всего это ОРГАНИЗАЦИОННЫЙ вопрос, а не технический. Технически все решается просто - 1) ты даешь информацию о последнем самом большом номере документа. 2) Пользователь руками вводит номер (подтверждает ввод, если ленивый) 3) После подписания документа (сдачи в архив, закртытия, и т.п.) - запрещается изменять номера всем, кроме админа (босса, ведущего, т.д.). 4) Пишешь процедурку, которая ищет возможные дырки и отдает их пользователю для разбора полетов. 5) Пользователи сами разбираются, когда и что надо им править, какие номера ставить - главное, чтобы был среди пользователей главный, который мог конфликт разрешить. И главное - это номер документа не должен быть первичным ключом! Хотя может быть наложено ограничение уникальности. А первичный ключ - суррогат на генераторе. Мой совет - еще раз обсудить ситуацию с постановщиком задачи. Решение всегда есть. С уважением, Алексей. ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2002, 11:52 |
|
Генератор
|
|||
---|---|---|---|
#18+
А я вот считаю, что юзеру нецелесообразно давать право чего-то там подтверждать/вводить! Во первых, есть документы, в нумерации которых "дырки" просто запрещены (счета-фактуры). Во вторых, когда за 1 минуту рождается около 10 документов (как у нас), то юзеры будут постоянно сталкиваться лбами пытаться вводить "свои" номера. В итоге они взвоют прибегут к программёру с перекошенными лицами :) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2002, 12:03 |
|
Генератор
|
|||
---|---|---|---|
#18+
если 10 штук в минуту - то это явная блокировка счетчика во время подтверждения счета. То есть он вне транзакции подготавливает счет (хоть три часа), потом жмет ок - документ быстро сохраняется и только в этот момент получает номер. Никаких роллбэков - номер получает только в последний момент. Но редактирование задним числом все равно делать придется - люди всегда люди. :) ... |
|||
:
Нравится:
Не нравится:
|
|||
26.12.2002, 12:07 |
|
|
start [/forum/topic.php?fid=40&msg=32084420&tid=1580980]: |
0ms |
get settings: |
8ms |
get forum list: |
14ms |
check forum access: |
3ms |
check topic access: |
3ms |
track hit: |
63ms |
get topic data: |
11ms |
get forum data: |
3ms |
get page messages: |
53ms |
get tp. blocked users: |
1ms |
others: | 16ms |
total: | 175ms |
0 / 0 |