Конференция "Базы" » Обрашение нескольких клиентов в одну запись. [D7, Firebird]
 
  • Xmen (11.12.14 07:11) [0]
    Привет!
    Делаю новую почтовую систему для своей организации. Старая версия этой проги работала без базы. Цель отправить файл по филиалам через ФТП. В ФТП пользуюсь готовым решением. Нужно архивировать и переименовать по шаблону файл. Шаблон типа такой xxxnnnmm.yyy  xxx - в какой отдел отправляется, yyy - от какой, nnn - текущий номер файла, mm - день.   База в Firebird 2.1. В головной отдел могут отправить сразу из нескольких подчиненных отделов. нужно контролировать чтобы nnn - номер файла не повторялась и было по порядку. Как можно это организовать? Генератор я пропустил так как номера файлов на начало дня обнуляется. Сделал таблицу OUT - от какого отдела IN - в какой ReysN - и номер файла. Ищется куда отправляется файл и получаем текущий номер файла и после архивирования идет переименование. А потом номер файла увеличиваем на единицу. Но это усложняться из за того что в одно время в этот запись обращается несколько клиентов. Как это организовать правильно. Читаю о транзакция но еще решение не нашел.
  • Sergey13 © (11.12.14 08:58) [1]
    >Нужно архивировать и переименовать по шаблону файл.
    Зачем? Почему сразу не именовать так файлы при отправке? Отправляет же тоже ваша программа? nnnmm - проще сразу заменить СКВОЗНЫМ номером (генерируемым идентификатором) и, возможно, нормальной датой(например для ручного поиска). Номер в течении дня - это вообще ни о чем, и кроме того может быть расчитан.
  • Xmen (11.12.14 09:43) [2]
    >>Номер в течении дня - это вообще ни о чем, и кроме того может быть расчитан.
    мне именно это нужно для определения последовательности . И нумерация нужно для того чтобы не получить одинаковых файлов.
  • junglecat © (11.12.14 09:55) [3]
    > нумерация нужно для того чтобы не получить одинаковых файлов

    ну так и нумеруй прямо перед отправкой, счетчик храни в коде, где собственно отправка и выполняется.
    если в течение дня прога может перезапускаться, сохраняй значение в файле/реестре/бд
  • Xmen (11.12.14 10:18) [4]
    я и так храню счетчик в базе. Из за  того что клиентских прог в одном отделе много то иногда за секунду за этим счетчиком обращаются много раз. Нужно сделать так чтобы первый обращавший заблокировал этот запись прочитал значение этого счетчика и записал обратно но результатом +1. После этого запись должен был доступен другим.
  • junglecat © (11.12.14 10:27) [5]
    start transaction;
    select @count = isnull(max(file_number),0)+1 from file_numbers with lock;
    update file_numbers set file_number = @count where file_id = @file_id;
    commit;
  • Кщд © (11.12.14 14:07) [6]
    >Xmen   (11.12.14 10:18) [4]
    чукча не читатель?
    http://www.firebirdsql.org/refdocs/langrefupd21-notes-withlock.html

    а вообще, вы пытаетесь сделать базу данных однопользовательской, сериализовав доступ
    это плохо
    это очень плохо
  • Xmen (12.12.14 06:49) [7]
    Наверно я неправильно задаю вопрос. мне нужно определит текущий номер документа для переименования, а потом нужно его увеличить его на единицу и записать обратно. Когда я работаю в одно пользовательском режиме то все в порядке. как нужно это сделать в много пользовательском режиме? Что бы не было deadlock а . Например я читаю значения счетчика для отдела "001" и оно равно "2", потом его нужно увеличить и записать обратно. Но в этот момент и другому клиенту нужно это значения счетчика. Он должен подождать пока я не закончу работу с этим счетчиком именно этого отдела, а потом обращаться этому счетчику. Как это сделать программно в Delphi?
    Есть таблица с полями отдел и счетчик. В Таблице каждый день удаляется записи. При обращение отдела счетчик увеличивается на единицу. Как правильно сделать так чтобы не было конфликта при записи на таблицу. Иногда из одного отдела может быт более одного обращения. У меня получается примерно так:
    Отдел Счетчик
    001 5
    004 1
    020 4
    001 1
    Программу делаю на Delphi. Работа со счетчиком.

    DMForm.dtsReys.ParamByName('otdel').AsString:=OtdelN;
    DMForm.dtsReys.Open;
    if DMForm.dtsReys.IsEmpty=False then
      begin
       Result:=IntToStr(DMForm.dtsReys.FieldByName('reysn').AsInteger+1);
       DMForm.dtsReys.Edit;
       DMForm.dtsReys.FieldByName('otdel').AsString:=OtdelN;
       DMForm.dtsReys.FieldByName('reysn').AsInteger:=StrToInt(Result);
      end
    else
      begin
       Result:='1';
       DMForm.dtsReys.Insert;
       DMForm.dtsReys.FieldByName('Otdel').AsString:=OtdelN;
       DMForm.dtsReys.FieldByName('reysn').AsInteger:=StrToInt(Result);
      end;
    DMForm.dtsReys.Post;
    DMForm.dtsReys.Close;
    DMForm.TR.CommitRetaining;



    select в dtsReys

    select r.*
    from REYS r
    where r.otdel=:otdel

  • Inovet © (12.12.14 07:04) [8]
    Если дыры недопустимы, то присваивать номер в триггере во время записи. Но тогда и удалять уже введённые документы нельзя, надо делать ещё один документ отменяющий предыдущий.

    В общем решение зависит от того, насколько это всё должно быть строго. А то может это простая блажь?
  • Sergey13 © (12.12.14 08:55) [9]
    2Xmen
    Сколько писем в день реально отправляет 1 отдел? Максимально?

    Используйте для нумерации не поле таблицы, а обнуляемый ежедневно генератор.

    Я так и не понял смысла переименования файлов при архивировании. Получили как хрен, заархивировали как редьку - зачем?

    ИМХО это бой с мельницами. Для примера - просто добавив к имени отдела текущий дататайм с милисекундами проблемы уникальности и последовательности решаются автоматически. Номер можно добавить и при выборке.
  • Xmen (12.12.14 09:24) [10]
    >>Я так и не понял смысла переименования файлов при архивировании. Получили как хрен, заархивировали как редьку - зачем?
    В день приходит окала 700 файлов разных объемов от 100 кб до 1 гб. Мы арендуем канал для связи с отделами. Для уменьшение объёма мы архивацию делаем. Переименование нужно для порядка и для сортировке файлов. Файлы хранятся в папках по дате и по месяцам. У нас более 40 отделов у каждого отдела может быт установлен программа клиент до 10 шт. и чтобы повторяющихся файлов не было нужно сделать переименование по шаблону.
    >>Для примера - просто добавив к имени отдела текущий дататайм с милисекундами проблемы уникальности и последовательности решаются автоматически.
    Как сказал если отправить файл в одно время хотя бы 3 клиента от одного отдела то и это не годиться.
  • junglecat © (12.12.14 10:02) [11]
    guid?
  • Кщд © (12.12.14 15:05) [12]
    >Xmen   (12.12.14 06:49) [7]
    что не ясно в "Кщд ©   (11.12.14 14:07) [6]"?
    1. заблокировали запись;
    2. инкреметировали;
    3. подтвердили/разблокировали/
  • Кщд © (12.12.14 15:06) [13]
    >junglecat ©   (12.12.14 10:02) [11]
    guid не гарантирует уникальность
  • Кщд © (12.12.14 20:57) [14]
    >Sergey13 ©   (12.12.14 08:55) [9]
    >Используйте для нумерации не поле таблицы, а обнуляемый ежедневно генератор.
    тогда будут "дырки" в нумерации
  • Jeer © (14.12.14 00:51) [15]
    Использовать генератор на основе DateTime
  • Sergey13 © (15.12.14 08:45) [16]
    2Кщд ©   (12.12.14 20:57) [14]
    >тогда будут "дырки" в нумерации
    Если заполнять в тригере, после нажатия на "Сохранить", то риск минимален.

    2Xmen   (12.12.14 09:24) [10]
    Ну так архивирует отправляющая сторона или принимающая?

    >Как сказал если отправить файл в одно время хотя бы 3 клиента от одного отдела то и это не годиться.
    Да ладно! С точностью до миллисекунды? Щаз. В крайнем случае сделать проверку на существование файла - дело 2 минут.
  • Кщд © (15.12.14 11:16) [17]
    >Sergey13 ©   (15.12.14 08:45) [16]
    >Если заполнять в тригере, после нажатия на "Сохранить", то риск минимален.
    исключение в триггере разрушит нумерацию
    сведёте вы этот риск к минимуму (только лишь инкрементируя генератор в триггере) или же максимизируете (нафаршировав триггер доп. логикой) - не важно
    важно, что риск есть
    в отличие от "Кщд ©   (12.12.14 15:05) [12]"
  • Sergey13 © (16.12.14 08:45) [18]
    2Кщд ©   (15.12.14 11:16) [17]
    Да я не против. Просто предложил вариант.
    Мне по прежнему кажется, что автор решает проблему, которой нет. Это даже не номер документа, который в принципе имеет право быть. Это просто имя файла.
 
Конференция "Базы" » Обрашение нескольких клиентов в одну запись. [D7, Firebird]
Есть новые Нет новых   [134427   +34][b:0][p:0.001]