Re: Multi Doc Numeration

2006-09-13 Пенетрантность Konstantin R. Beliaev


Oleg LOA wrote:

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


Я когда-то даже придумал такой,
http://konstb.newmail.ru/interbase/gennum.htm
а все тут спросили: ну и зачем? :-)



Re: Multi Doc Numeration

2006-09-08 Пенетрантность Oleg LOA
Константин [EMAIL PROTECTED] wrote in message news:[EMAIL PROTECTED]
А если серьёзно, кто что думает по этому поводу ?

Предлагаю подумать на следующие темы самостоятельно;

1) Сериализация доступа к механизму создания новых номеров
2) Параметрытранзакции lock_writе и wait



Re: Multi Doc Numeration

2006-09-07 Пенетрантность Alexey Popov



Тебе нужна сериализация.
При генерации нового документа запускаешь транзакцию с параметрами

wait
lock_write=имя_некой_таблицы
protected

Такие транзакции будут сериализованы. Внутри вычисляешь
номер нового документа обычными sql операторами.


--
--- Home Page http://ok.novgorod.net/ap ---




Re: Multi Doc Numeration

2006-09-07 Пенетрантность Ded


Константин wrote:

Вопрос: когда я, с таким подходом, напорюсь на грабли ? И на какие ?
CREATE PROCEDURE DOC_PROVODKA (
doc_id bigint)
as
declare variable i bigint;
declare variable tid bigint;
declare variable ftid bigint;
begin
// Stop - семафор,
// sleep - UDF наподобие Application.ProcessMessages в Delphi
  while (gen_id(stop, 0)  0)) do sleep(100);
  i = gen_id(stop, 1);


  Здесь. Запросто можешь получить в i не 1, как ты думаешь, а 2,3...N


  select TYPE_ID, to_id from vw_doc where id = :doc_id into :tid, :ftid;

  select max(num) from doc where TYPE_ID = :tid into :i;


  Здесь. Либо лишний индекс либо будешь курить бамбук.


  update doc set num = z(:i) + 1 where id = :doc_id;

  select max(UserNUM) from doc where TYPE_ID = :tid and to_id = :ftid into :i;


  Здесь. Либо лишний индекс либо будешь курить бамбук.


  update vw_doc set UserNUM = z(:i) + 1 where id = :doc_id;

  i = gen_id(stop, -1);


  Здесь. Запросто можешь получить в i не 0, как ты думаешь, а 1,2,3...N


end



А если серьёзно, кто что думает по этому поводу ?


  Очередной лисапет с до боли знакомыми квадратными колёсами.


Если можно, подскажите варианты решения ... желательно опробованные на
практике ...


  Раз уж тебе приспичило создавать бутылочные горлышки в системе и 
выстраивать всех в очередь, заведи табличку


Номера
Тип документа not null PK
Следующий номер int

и получай номер как-нибудь так:

Starttransaction
Repeat
 Try
   Update Номера Set Следующий номер = Следующий номер +1
   Where Тип документа = Чаво нада;
   Select Следующий номер
From Номера
Where Тип документа = Чаво нада;
   Получилося:=True;
   Except Do
Получилося:=False;
 end;
Until Получилося;
Тыр-пыр-восемь дыр, ну там инсёрт или ещё чего нада для щастья
Commit;

Это для read_commited. А ващета про генерацию людских, а не 
искуственных номеров, подробные статейки есть, и вроде даже у ДК на сайте...


--
Regards. Ded.



Re: Multi Doc Numeration

2006-09-07 Пенетрантность Ded


Alexey Popov wrote:




Тебе нужна сериализация.
При генерации нового документа запускаешь транзакцию с параметрами

wait
lock_write=имя_некой_таблицы
protected

Такие транзакции будут сериализованы. Внутри вычисляешь
номер нового документа обычными sql операторами.



   Мля, на колу мочало, начинай сначала, 2001-й год вроде, учител Йода 
вернулся. Чтоб удержать одну запись, крайне необходимо блокировать 
таблицу целиком. МП, крутани ПНХ движок до отсечки, а?


--
Regards. Ded.



Re: Multi Doc Numeration

2006-09-07 Пенетрантность Shiliaev Ruslan


Константин пишет:

Hi, многоуважаемый All!

Есть табличка шапок документов скажем

CREATE TABLE DOC ( IDBIGINT, TYPE_ID   BIGINT, DATE_DOC
TIMESTAMP, NUM   BIGINT, UserNUM   BIGINT, From_ID   BIGINT, 
TO_ID BIGINT, ... );


1) Есть условие что нумерация (NUM) для каждого типа документов
(type_id) должна быть уникальной

2) Есть условие что для каждого контрагента получателя (To_ID), в
зависимости от типа документа (Type_id) идёт своя нумерация


Привет!

Заведи таблицу с номерами для разных получателей и типов документов:

CREATE TABLE DOC_NUM(
TO_ID BIGINT NOT NULL,
TYPE_ID BIGINT NOT NULL,
MAX_DOC_NUM INT NOT NULL);


ALTER TABLE DOC_NUM ADD CONSTRAINT PK_DOC_NUM PRIMARY KEY (TO_ID, TYPE_ID);

В триггере на BI что то типа:
...
IF (EXISTS(SELECT 1 FROM DOC_NUM WHERE TO_ID = NEW.TO_ID AND TYPE_ID =
NEW.TYPE.ID)) THEN
UPDATE DOC_NUM SET MAX_DOC_NUM = MAX_DOC_NUM + 1 WHERE TO_ID =
NEW.TO_ID AND TYPE_ID = NEW.TYPE.ID;
ELSE
INSERT INTO DOC_NUM(TO_ID, TYPE_ID, MAX_DOC_NUM) VALUES (NEW.TO_ID,
NEW.TYPE_ID, 1);

SELECT MAX_DOC_NUM FROM DOC_NUM WHERE TO_ID = NEW.TO_ID AND TYPE_ID =
NEW.TYPE.ID INTO NEW.NOM;

И пиши в коротких R/C транзакциях. В случае облома - sleep(100) и пробуй
еще.

--
Удачи!

Shiliaev Ruslan



Re: Multi Doc Numeration

2006-09-07 Пенетрантность Alexey Popov




Ded wrote:


Такие транзакции будут сериализованы. Внутри вычисляешь
номер нового документа обычными sql операторами.


   Мля, на колу мочало, начинай сначала, 2001-й год вроде, учител Йода 
вернулся. Чтоб удержать одну запись, крайне необходимо блокировать 
таблицу целиком. МП, крутани ПНХ движок до отсечки, а?


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

--
--- Home Page http://ok.novgorod.net/ap ---




Re: Multi Doc Numeration

2006-09-07 Пенетрантность Sergiy S. Tkachenko


Что если создавать для каждого нового типа документов свой генератор,
по аналогии как в Firebird создаются домены RDB$X



Re: Multi Doc Numeration

2006-09-07 Пенетрантность Ded


Константин wrote:


 По типу документа ещё можно ...
 А по контрагенту ?
 Что скажут кодописатели насчёт ~5000 генераторов ? :)
 Я не знаю точно, но какое-то ограничение на к-во генераторов
 существует же ...


   Странный ты, ей-богу. Тыщу раз говорили ведь - при создании 
документов они не нумеруются человеческими номерами. Нумеруются при 
утверждении и как правило скопом, отдельной функцией. Потому что там, к 
бабке не ходи, упорядоченность по номерам должна соответствовать 
упорядоченности по датам. И если более ранним номера не присвоены, более 
поздние надо тоже придержать. А для связей держут искусственные ключи, 
на одном генераторе на всех. А пользователю его не показывают. Или 
показывают пока не присвоен человеческий номер, как нибудь типа 
'Проект N '||ID. Ну и заведи ты для выходной нумерации табличку каталог 
типов, нужен составной ключ - m:n тип-контрагент, инсёрть туда на 
инсёрт-триггерах парентов с полем текущий номер 0, будет у тебя в ней 
хоть 5 000 000 псевдогенераторов, которые будешь лочить-инкать и читать 
в функции нумерации. Это всегда делается через захватываемый ресурс, а 
не внетранзакционный генератор. Даже если ограничений по дате нет.



Двоечник на любое - Надо! отвечает - Зачем?


  Хреновый из тебя двоечник. Не думаешь - зачем. Пилить бросаешься.

--
Regards. Ded.





Re: Multi Doc Numeration

2006-09-07 Пенетрантность Sergey Philippov


Константин пишет:

// Stop - семафор,
// sleep - UDF наподобие Application.ProcessMessages в Delphi
  while (gen_id(stop, 0)  0)) do sleep(100);
  i = gen_id(stop, 1);
Хм, sleep... Чего уж мелочиться, давай сразу 
CreateMutex/WaitForSingleObject/ReleaseMutex :)


--
wbr, ps
ps-at-azs-ru