Модераторы: MetalFan
  

Поиск:

Ответ в темуСоздание новой темы Создание опроса
> Как избежать одновременного доступа к процедуре 
:(
    Опции темы
oleg153
Дата 30.4.2009, 19:25 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 1.3.2007

Репутация: нет
Всего: нет



Приложение работает с таблицей SQL - (Таб-1)

По Таймеру :
По таблице делаю Выборку и для выбраных записей выполняю расчеты (бывает долго, 2-5 сек) зависимости от результата меняю одно из полей записи. 
Возврат результата занимает от милисекунд до 2-5 секунд.

При этом для данного приложения я сделал (ActiveX (exe) сервер) несколько методов, которые
также используют теже процедуры работы с базой которые описаны в основной (VCL) форме.

Чтоб избежать одновременного доступа к процедуре по событию Таймера (VCL-поток) и вызова этой процедуры (или другой, которая тоже работает с Таб-1) внешним приложением через Метод, я использовал Критическую Секцию и выполняю процедуры как через метод описаный в библиотеке, так и в основной форме по таймеру только отработав вход -выход в Критическую секцию.

Думал это поможет , НО ВСЕ РАВНО ПРОИСХОДИТ ОДНОВРЕМЕННЫЙ ДОСТУП К ДАННЫМ , значит критическая секция или не действует или что-то я не понимаю. 


Подскажите КАК сделать так чтоб при наличии нескольких процедур, которые могут вызываться в основной форме и извне, не происходил одновременный запуск , что рушит базу (вернее возникает сбой)
PM MAIL   Вверх
Rrader
  Дата 1.5.2009, 07:57 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Inspired =)
***


Профиль
Группа: Экс. модератор
Сообщений: 1535
Регистрация: 7.5.2005

Репутация: 6
Всего: 191



Цитата(oleg153 @  1.5.2009,  01:25 Найти цитируемый пост)
значит критическая секция или не действует или что-то я не понимаю. 

Скорее второе. Можете показать Ваш примерный код работы с секцией?


--------------------
Let's do this quickly!
Rest in peace, Vit!
PM MAIL Skype   Вверх
oleg153
Дата 4.5.2009, 15:03 (ссылка) | (нет голосов) Загрузка ... Загрузка ... Быстрая цитата Цитата


Новичок



Профиль
Группа: Участник
Сообщений: 34
Регистрация: 1.3.2007

Репутация: нет
Всего: нет



В основной форме

Код

  private
    { Private declarations }
    CritSec:TRTLCriticalSection;
    DServ:Variant;
  public
    { Public declarations }
    procedure LockForm;
    procedure UnlockForm;
    procedure SetData1;
    procedure SetData2;
  end;

var
  Form1: TForm1;

implementation

{$R *.dfm}

procedure TForm1.SetData1;
begin
with ADOQuery1 do
 begin
  Close;
  Open;
  if RecordCount >0 then
   begin
    First;
    while not Eof do
      begin
       Edit;
       FieldByName('lockState').AsString:= 'lock';
       Post;
        // для тестирования.  Внешняя задержка
       if VarType(DServ) = varDispatch then
        begin
         DServ.Test1(7000);
        end
        else
        begin
         ShowMessage('Нет подключенного сервера');
        end;
       //Sleep(7000); // для тестирования.  Внутренняя задержка
       Next;
      end;
   end;
 end; //with
end;

procedure TForm1.SetData2;
begin
with ADOQuery1 do
 begin
  Close;
  Open;
  if RecordCount >0 then
   begin
    First;
    Edit;
    FieldByName('lockState').AsString:= 'unlock';
    Post;
   end;
 end; //with
end;

procedure TForm1.Button1Click(Sender: TObject);
begin
Label1.Color:=clRed;
 try
  LockForm;
  SetData1;
 finally
  UnlockForm;
 end;
Label1.Color:=clGreen;
end;

procedure TForm1.Button2Click(Sender: TObject);
begin
 //Подключение к серверу.
  DServ := CreateOLEObject('DataServer.OfflineServer1');
end;

procedure TForm1.Button3Click(Sender: TObject);
begin
 //Отключение от сервера.
 if VarType(DServ) = varDispatch then
  begin
   DServ := Unassigned;
  end
  else
  begin
   ShowMessage('Нет подключенного сервера');
  end;
end;

procedure TForm1.FormCreate(Sender: TObject);
begin
 try
  {Открываем сеанс связи с б.д.}
  ADOConnection1.Open;
 except
  ShowMessage('Не удалось установить связь с б.д., сервер не доступен.');
 end;
 {инициализируем Критическую Секцию}
 InitializeCriticalSection(CritSec);
end;

procedure TForm1.FormDestroy(Sender: TObject);
begin
 {Закрываем сеанс связи с базой данных}
  ADOConnection1.Close;
 {Закрываем Критическую секцию}
  DeleteCriticalSection(CritSec);
end;

{Захват потоком критической секции}
procedure TForm1.LockForm;
 begin
  EnterCriticalSection(CritSec);
 end;

 {Освобождение потоком критической секции}
procedure TForm1.UnlockForm;
 begin
  LeaveCriticalSection(CritSec);
 end;


Смоделировал ошибку.

Если procedure: SetData1 вызывается из Основной формы, а SetData2 из Клиентского приложения, тогда :
 - Если пауза ( Sleep() ) отрабатывается в Основной форме - тогда при попытке исполнить Клиентом SetData2 - он не исполняется, ждет отработки SetData1.
 - Если пауза исполняется на ВНЕШНЕМ сом-сервере к которому подключаю Основной, и на этом 2-ом сервере отрабатывается пауза (это аналок действий которые на нем отрабатываются в реали и требуют время) - тогда по неясным пока мне причинам Защита через Критическую секцию работать перестает, и можно исполнить SetData2 ДО окончания исполнения SetData1.

При этом SetData1 и SetData2 работают с одним набором данных и НЕЛЬЗЯ чтоб SetData2 мог исполниться до ПОЛНОГО исполнения SetData1

Добавлено через 2 минуты и 43 секунды
Конечно при описании метода который использует SetData2 я также использую Крит. секцию.

Код

procedure Ttest15.KlientSetData(const ScriptCode: WideString);
begin
 try
  Form1.LockForm;
  Form1.SetData2;
 finally
  Form1.UnlockForm;
 end;
end;


PM MAIL   Вверх
  
Ответ в темуСоздание новой темы Создание опроса
Правила форума "Delphi: ActiveX/СОМ/CORBA"

Rrader
Girder

Запрещено:

1. Публиковать ссылки на вскрытые компоненты

2. Обсуждать взлом компонентов и делиться вскрытыми компонентами


  • Литературу по Delphi обсуждаем здесь
  • Действия модераторов можно обсудить здесь
  • С просьбами о написании курсовой, реферата и т.п. обращаться сюда
  • Вопросы по реализации алгоритмов рассматриваются здесь
  • 90% ответов на свои вопросы можно найти в DRKB (Delphi Russian Knowledge Base) - крупнейшем в рунете сборнике материалов по Delphi
  • Вопросы по SQL и вопросы по базам данных, не связанные с Delphi, задавать здесь

Если Вам помогли, и атмосфера форума Вам понравилась, то заходите к нам чаще! С уважением, Rrader, Girder.

 
0 Пользователей читают эту тему (0 Гостей и 0 Скрытых Пользователей)
0 Пользователей:
« Предыдущая тема | Delphi: ActiveX/СОМ/CORBA | Следующая тема »


 




[ Время генерации скрипта: 0.0411 ]   [ Использовано запросов: 22 ]   [ GZIP включён ]


Реклама на сайте     Информационное спонсорство

 
По вопросам размещения рекламы пишите на vladimir(sobaka)vingrad.ru
Отказ от ответственности     Powered by Invision Power Board(R) 1.3 © 2003  IPS, Inc.