Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2003.09.04;
Скачать: [xml.tar.bz2];

Вниз

Как реализовать неперекрываемость данных?   Найти похожие ветки 

 
Riko   (2003-08-05 11:01) [0]

При создании записи в многопользовательском режиме работы есть вероятность что два пользователя получат один и тот-же номер вносимого документа....В результате возникнет перекрытие данных одного юсера другим, более поздним.
Ну например:
function TFNewNakl.GetLasNumProd:Integer;
begin
IBQuery1.Active:=false;
IBQuery1.SQL.Clear;
IBQuery1.SQL.Add(" SELECT DISTINCT MAX( TABLE.NUM )");
IBQuery1.SQL.Add(" MAX_NUM FROM TABLE");
IBQuery1.Active:=true;
Result:=IBQuery1.Fields[0].AsInteger+1;//присвоили новый номер
end;
После чего заполняется документ и по окончании:
IBTransaction1.Commit;
Но если в момент заполнения документа другой , более шустрый юсер , получит номер таким-же способом, то его номер будет идентичен предыдущему.....КАК БОРОТЬСЯ? Заранее спасибо.


 
Ann   (2003-08-05 11:02) [1]

бороться с этим лучше использованием генераторов.


 
Соловьев   (2003-08-05 11:06) [2]

и блокировкой записи - это уже настройка уровня изоляции транзакции.


 
Zacho   (2003-08-05 11:12) [3]

Еще совет: почитай статьи на http://wwww.ibase.ru/develop.htm , особенно касающиеся транзакций и генераторов.
Ну и, естественно, что-нибудь про первичные ключи и уникальные индексы.


 
MsGuns   (2003-08-05 13:06) [4]

Трабла от недостатка опыта. Во-первых, в промежуток времени один
и тот же № действительно могут ввести хоть 100 человек (что в реале, весьма маловероятно - максимум 2-3), тем более, что в некоторых программых он предоставляется узеру автоматически.
Но постятся записи последовательно, поэтому в проге должен быть предусмотрена ситуация возврата "опоздавшим" узерам незаписанного в БД документа с соотв.сообщением. Либо формировать этот номер автоматически в цикле, модифицируя № каждый раз пока не запостится.

>Ann © (05.08.03 11:02)
>бороться с этим лучше использованием генераторов.

Для нумерации "живых" документов совет рискованный. Получать "рваные" последовательности номеров физических документов - это не каждому рук-лю или главбуху придется по душе.
К тому же что делать 1 января, когда нумерация должна сбрасываться ?




 
АлексейК   (2003-08-05 13:10) [5]

А какая база данных то?


 
Zacho   (2003-08-05 13:19) [6]


> MsGuns © (05.08.03 13:06)
> Но постятся записи последовательно, поэтому в проге должен
> быть предусмотрена ситуация возврата "опоздавшим" узерам
> незаписанного в БД документа с соотв.сообщением. Либо формировать
> этот номер автоматически в цикле, модифицируя № каждый раз
> пока не запостится.

Imho, самый "правильный" способ "бездырочной" нумерации - получать новый номер после окончания создания документа непосредственно перед вставкой записей в БД с помощью SELECT MAX(..)+1 .. ,все это в отдельной короткой транзакции SNAPSHOT TABLE STABILITY WAIT с явным резервированием таблицы. Тогда не будет ни каких конфликтов, и никакие циклы не нужны.


 
MsGuns   (2003-08-05 13:46) [7]

>Zacho © (05.08.03 13:19)

Совет хороший, но не панацейный. В частности не решает проблем заполненности "дырок" (когда документ был удален, а на его место надо добавить новый с тем же номером) Да и вообще не советовал бы никому завязываться на уникальность номеров в делопроизводстве - могут, еще как могут встречаться документы с одинаковым номером ! (Например, выписаны 2 варианта накладных покупателю, один из которых впоследствии будет удален)




 
Zacho   (2003-08-05 14:07) [8]


> MsGuns © (05.08.03 13:46)
> Совет хороший, но не панацейный. В частности не решает проблем
> заполненности "дырок" (когда документ был удален, а на его
> место надо добавить новый с тем же номером)

Эта проблема тоже вполне решаема - вместо SELECT MAX(doc_num)+1 ... делаем
SELECT MIN(T.doc_num)+1
FROM TABLE T
LEFT JOIN TABLE T1 ON T1.DOC_NUM=T.DOC_NUM+1
WHERE T1.DOC_NUM IS NULL

> Да и вообще не советовал бы никому завязываться на уникальность
> номеров в делопроизводстве - могут, еще как могут встречаться
> документы с одинаковым номером !

Полностью согласен ;-)


 
Riko   (2003-08-06 10:01) [9]

Спасибо всем огромное, более или менее картинка ясна...


 
Sergey13   (2003-08-06 10:09) [10]

Еще могу посоветовать разнести понятие Id и Номер документа по разным полям.


 
Ann   (2003-08-06 10:25) [11]


> MsGuns © (05.08.03 13:06)
> >Ann © (05.08.03 11:02)
> >бороться с этим лучше использованием генераторов.
> К тому же что делать 1 января, когда нумерация должна сбрасываться
> ?

я не говорила про нумерацию документов, я говорила про ID...
а нумеровать документы можно или в другом поле или просто в вычисляемом поле (смотря что требуется...)


 
Sir Alex   (2003-08-06 11:07) [12]

Тогда нет проблем:

В БД создать генератор:
CREATE GENERATOR GEN_TABLE_ID;

function TFNewNakl.GetLasNumProd:Integer;
begin
IBQuery1.Active:=false;
IBQuery1.SQL.Clear;
IBQuery1.SQL.Add(" SELECT GEN_ID(GEN_TABLE_ID,1) FROM RDB$DATABASE");
IBQuery1.Active:=true;
Result:=IBQuery1.Fields[0].AsInteger;//присвоили новый номер
end;


Если используются компоненты FIBPlus, можно еще проще:
function TFNewNakl.GetLasNumProd:Integer;
begin
( "GEN_TABLE_ID",1)
Тогда нет проблем:

В БД создать генератор:
CREATE GENERATOR GEN_TABLE_ID;

function TFNewNakl.GetLasNumProd:Integer;
begin
IBQuery1.Active:=false;
IBQuery1.SQL.Clear;
IBQuery1.SQL.Add(" SELECT GEN_ID(GEN_TABLE_ID,1) FROM RDB$DATABASE");
IBQuery1.Active:=true;
Result:=IBQuery1.Fields[0].AsInteger;//присвоили новый номер
end;


Если используются компоненты FIBPlus, можно еще проще:
function TFNewNakl.GetLasNumProd:Integer;
begin
Result:=FIBDatabase.Gen_ID ("GEN_TABLE_ID",1)
end;


P.S. И еще у FIBDataSet есть возможность в дизайнере указать генератор и ключевое поле, тогда вообще не надо беспокоиться о кодах.

Успехов...


 
Sir Alex   (2003-08-06 11:10) [13]

ОЙ, чё-т я не посмотрел, кто запостил жту тему, подумал, что это все надо Ann... 8)


 
Ann   (2003-08-06 11:13) [14]

:) нет, мне это не надо :))


 
MsGuns   (2003-08-06 12:44) [15]

Дополнение к Sergey13 © (06.08.03 10:09):
Советовал бы добавить еще одно поле дополнительно к № документа (которое Int), которое я назвал префикс документа и обозначить его VARCHAR c длиной, допустим, 24, причем первый символ-всегда "служебный". Для чего ?

Например, накладные

Реальный Поля таблицы БД
№ NUMBER(LongInt) ( 24) Дополнение к Sergey13 © (06.08.03 10:09):
Советовал бы добавить еще одно поле дополнительно к № документа (которое Int), которое я назвал префикс документа и обозначить его VARCHAR c длиной, допустим, 24, причем первый символ-всегда "служебный". Для чего ?

Например, накладные

Реальный Поля таблицы БД
№ NUMBER(LongInt) NUMNDX VARCHAR(24)
-------------------------------------------------------
13786Возврат 13786 tВозврат
Возврат13786 13786 lВозврат

Анализ и отсекание упр.символа l/t выполнять на клиенте или вообще на сервере с возвращением одного поля как реального №

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




 
HSolo   (2003-08-06 15:23) [16]

Тогда уж, может, 3 поля?
№ документа (Int)
префикс (varchar)
служебное (int или char(1))
И ничего отсекать не надо


 
Riko   (2003-08-12 10:10) [17]

ID и номер дока и так на разных полях, за табличные беспокойств нет.
ID генератор и так стоит, вопрос идет о неперекрываемости номера документов, к примеру накладной.... Если заполнять дырочки впоследствии, то нумерация документов будет запутанной, то -есть более поздний документ может быть с меньшим номером и т.п. Наиболее безопасным мне кажется генерация номера документа при Commit (совет Zacho ©), а на печать не посылать без проведения транзакции...
Всем спасибо...


 
Zacho   (2003-08-12 10:22) [18]


> Riko © (12.08.03 10:10)

Если ты выбрал этот способ, то на всякий случай еще раз (и немного подробнее) повторю:
Получение номера и вставку документа нужно делать в отдельной и как можно более короткой транзакции с блокированием всей таблицы, т.е. параметры транзакции должны быть типа:
write
consistency
wait
lock_write=имя_таблицы
exclusive


 
Riko   (2003-08-13 09:21) [19]

Огромное спасибо, пробую....



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2003.09.04;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.5 MB
Время: 0.01 c
14-10944
malkolinge
2003-08-14 19:32
2003.09.04
А кто такой деятель с ником имя(красного цвета перечеркнутый)


7-10988
Poma
2003-06-21 17:04
2003.09.04
Как отличить CD-ROM, floopy и логический диск


7-10986
Дмитрий777
2003-06-24 13:37
2003.09.04
Передавать файлы по частям


1-10677
Боян Георгиев
2003-08-20 23:52
2003.09.04
TMainMenu


3-10563
Karnegi
2003-08-15 10:55
2003.09.04
Помогите с фильтрацией по дате





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский