| Ответ 1:
Самое дешевое решение - завести поле, в которое будет записываться ID usera
перед началом операции.
Перед началом обновления данных выполняете
следующее. 1. При старте программы каждому юзеру раздаете уникальный
ID. 2. Перед началом обновления данных записываете ID в поле в и коммитете
данные. После этого поле будет залочено для этого юзера. 3. Вносите
изменения. 4. В блокирующее поле записываете 0 и коммитете.
Перед
началом обновления, проверяете чему равно значение блокирующего поля. Если оно
не нулевое, то вы не только сможете сообщить, что запись заблокирована, но и
сказать кем именно.
Если не делать ничего подобного то запросто при
многопользовательской работе можно получить deadlock на сервере а есть не
очень хорошо.
Ответ 2:
Так сделать нельзя. Можно по другому. Оцени критические ситуации и поставь
проверку на триггер или еще лучше сделай с помощью CHECK. Например:
колличество на складе не может быть меньше 0 CHECK TOVAR_COUNT>0 Если один
из клиентов изменил количество , а второй попытался снять больше чем есть на
складе - то сервер выдаст ошибку, которую ты можешь обработать
программой.
Очень хорошая книга по этой теме П.В. Шумаков - Дельфи 3 и
разработка приложений баз данных. После ее прочтения 80% твоих вопросов будут
решены.
Ответ 3:
Думаю, что Вашу задачу можно решить следующим путем. На сервере метод,
который осуществляет обработку данных. "закрыть" критической
секцией.
В начале критическую секцию необходимо объявить в составе класса
или отдельно:
SectionLock: TCriticalSection;
|
Затем:
procedure TForm1.FormCreate(Sender: TObject); begin SectionLock := TCriticalSection.Create; end;
procedure TForm1.FormDestroy(Sender: TObject); begin SectionLock.Free; end;
|
Теперь при инициализации Вашего метода можно использовать SectionLock:
SectionLock.Acquire; try DoSomething; finally SectionLock.Release; end;
// или
SectionLock.Enter; try DoSomething; finally SectionLock.Leave; end;
|
Когда поток достигает критической секции, то все что заключено в этой секции
перестает реагировать на любые внешние воздействия до момента выхода из
критической секции. Теперь на попытку обращения к серверу другого клиента в
качестве результата можно возвращать значение, которое будет идентифициороваться
как "Занято". Например:
if Lock then "Ответ - занято"
SectionLock.Enter; try Lock := True; DoSomething; finally SectionLock.Leave; Lock := False; end;
|
P.S. Что бы сервер мог одновременно реагировать на несколько запросов, его
необходимо реализовать в СОМ технологии. |