imho.ws
IMHO.WS  

Вернуться   IMHO.WS > Компьютеры > Программирование
Опции темы
Старый 28.10.2005, 14:59     # 1
Galush
Banned
 
Аватар для Galush
 
Регистрация: 08.08.2005
Адрес: ЗАВОД на УКЕ
Сообщения: 52

Galush презирают в этих краях
DELPHI Нужна помощь! Обновление БД.

Столкнулся с проблемой при разработке многопользовательской БД.
Задача такая:
С одной таблицей работают два пользователя в одно время.
Первый пользователь изменяет данные в таблице и сохраняет их.
В то время Второй пользователь работая с этой же таблицей не получает обновленные данные, т.е. работает с неизмененными данными.
Внимание вопрос:
Как заставить сервер БД обновлять данные у всех пользователей?
Для справки. БД paradox.
Galush вне форума  
Старый 28.10.2005, 17:55     # 2
dyr_farot
Advanced Member
 
Регистрация: 23.08.2003
Сообщения: 442

dyr_farot Нимб уже пробиваетсяdyr_farot Нимб уже пробивается
IMHO никак ( это, вобще-то нерешаемая проблема ) откуда сервер может знать нужны ли пользователю эти обновленные данные? ( а еще и такой сервер как парадокс... )
dyr_farot вне форума  
Старый 29.10.2005, 00:14     # 3
_Lynx_
Junior Member
 
Регистрация: 11.10.2005
Сообщения: 63

_Lynx_ Путь к славе только начался
Только заставляя пользователей обновлять данные вручную.
А вообще почитай про эти проблемы:
* неповторяющееся чтение (non-repeatable read);
* "грязное" чтение (dirty read) - чтение данных, которые были записаны откатанной транзакцией;
* потерянное обновление (lost update);
* фантомная вставка (phantom insert).
А также уровни изоляции и блокировки.
_Lynx_ вне форума  
Старый 29.10.2005, 15:06     # 4
Willow
Junior Member
 
Регистрация: 23.12.2003
Адрес: Киев
Сообщения: 118

Willow Реально крут(а)Willow Реально крут(а)Willow Реально крут(а)Willow Реально крут(а)
Единственный способ - это перечитывание клиентом данных.
Обычно, в таких случаях, клиент с некоторой частотой провереяет не обновлялись ли на сервере данные (к примеру считывает время последненго обновления из специальной таблицы), и если обновляллись то перечитывает их самостоятельно.
Willow вне форума  
Старый 30.10.2005, 01:17     # 5
kot_
Junior Member
 
Аватар для kot_
 
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67

kot_ Путь к славе только начался
Цитата:
Сообщение от Galush
Столкнулся с проблемой при разработке многопользовательской БД.
Задача такая:
С одной таблицей работают два пользователя в одно время.
Первый пользователь изменяет данные в таблице и сохраняет их.
В то время Второй пользователь работая с этой же таблицей не получает обновленные данные, т.е. работает с неизмененными данными.
Внимание вопрос:
Как заставить сервер БД обновлять данные у всех пользователей?
Для справки. БД paradox.
Используй RDM и подпиши клиента на нужные тебе события (например вставку записи) через интрефейс СОМ.
__________________
kot_ вне форума  
Старый 31.10.2005, 13:18     # 6
dyr_farot
Advanced Member
 
Регистрация: 23.08.2003
Сообщения: 442

dyr_farot Нимб уже пробиваетсяdyr_farot Нимб уже пробивается
kot_, подписаться пародоксу... очень сомневаюсь что получится...
dyr_farot вне форума  
Старый 31.10.2005, 16:04     # 7
kot_
Junior Member
 
Аватар для kot_
 
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67

kot_ Путь к славе только начался
Я имел виду не парадокс - а создать трехзвенку - и работать с ней. Я ведь так понимаю - еслиб задача совем мизирная была и одноразовая - и проблем бы особых не было. Плюсы - можно спокойно забыть о недостатках файлсервера, спокойно реализовать все бизнес правила, создать нужный функционал. Минус - прийдется попарится с СОМ-серверами и внести изменения в существующую программу. Иногда конечно подобные минуса перевешивают все плюса - но тут уже по месту.
__________________
kot_ вне форума  
Старый 02.11.2005, 15:59     # 8
gscorp
Newbie
 
Регистрация: 21.10.2005
Сообщения: 24

gscorp Нуль без палочки
Цитата:
kot_:
Я имел виду не парадокс - а создать трехзвенку - и работать с ней
IMHO Задача мягко говоря грандиозна - превращать файлсервер в версионник... гм.... я бы не решился.
Цитата:
kot_:
Минус - прийдется попарится с СОМ-серверами
COM - Сервера под делфей пишится на раз, вопрос здесь один разруливание доступа к разделяемому ресурсу...
__________________
в память о 2:5049/70
gscorp вне форума  
Старый 02.11.2005, 16:31     # 9
kot_
Junior Member
 
Аватар для kot_
 
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67

kot_ Путь к славе только начался
Для начала - необязательно для этого заморачиваться с версионностью - при вставке/изменении записи - для начала генерить событие и обработать его в приложении. Ничего особо грандиозного в данном случае нет и задачу способно решить без особо дополнительных расходов. Можно в принципе - что бы не переделывать приложение - реализовать отдельно сервер уведомлений. Это будет достаточно простое решение - правда не очень изящное. Вопрос ведь был задан - как уведомить пользователя о изменении, а не как реализовать версионность. Ком -сервер вполне эту задачу может выполнить, а если понадобится разруливание доступов - это тоже в тех же дельфях телается за день.
__________________
kot_ вне форума  
Старый 03.11.2005, 10:39     # 10
Galush
Banned
 
Аватар для Galush
 
Регистрация: 08.08.2005
Адрес: ЗАВОД на УКЕ
Сообщения: 52

Galush презирают в этих краях
Цитата:
kot_:
Можно в принципе - что бы не переделывать приложение - реализовать отдельно сервер уведомлений.
Можно как нить по подробнее.
Galush вне форума  
Старый 03.11.2005, 16:32     # 11
kot_
Junior Member
 
Аватар для kot_
 
Регистрация: 19.11.2004
Адрес: Dnepropetrovsk
Пол: Male
Сообщения: 67

kot_ Путь к славе только начался
Блин. Сервак падает раз, за разом.
Че за байда?
Что бы написать и отправить пост - четыре часа уходит
******************
Можно. Один из вариантов - создаешь сервер уведомлений на основе хотябы тогоже билдеровского РДМ-модуля. Делается это достаточно просто - создаешь новый проект - в него добаваляешь RDM-модуль(не забудь поставить галочку в эвентсах) и модель выбирай о вкусу - апартмент - на каждого юзера запускается отдельное приложение например, я предпочитаю фри - но эта модель достаточно сложна. Сохраняешь и лезешь в Type Library и в интерфейсах своего класса прописываешь необходимые тебе функции. В импл-модуле определяешь их. После определяешь какие события будут ловиться на твоих клиентах. Соответственно объявляешь их. Дальше свой сервер запускаешь с параметром /regserver. В принципе с сервером все. А ну соответственно в классе формы и классе интерфейса надо определить функции - это ниже. Для клиента прийдется написать заголовочный файл интерфейса класса событий и подключить в проект. Выглядит примерно так:
Код:
#if !defined (NOTCREMOUTESINK_H__)
#define NOTCREMOUTESINK_H__

#include <atlvcl.h>
#include <atlbase.h>
#include <atlcom.h>
#include <ComObj.HPP>
#include <utilcls.h>
#include "..\server\srvnotc_TLB.h"// Файл интерфейсов твоего сервера
//генерируется автоматически в проекте сервера.
typedef void __fastcall (__closure *TNewMessageEvents)( long employeeid );
typedef void __fastcall (__closure *TChangeStatusEvents)( BSTR contractid,long pointid );
//Ловим два события: Вызов фукции сервера GetNewMessage()
//получаем в нем идентификатор пользователя !которому! направлено сообщение
//Изменение статуса записи - событие генерируется при вызове функции InsertContract&UpdateContract
//Остальные сделаешь по примеру - а то листинг   
//Твой класс уведомлений
class TnOTCRemouteSink :
 public TEventDispatcher<TnOTCRemouteSink, &DIID_InOTCRemouteModuleEvents>
{
protected:
 TNewMessageEvents                      FOnNewMessage;
 TChangeStatusEvents                    FOnChangeStatus;
...
 HRESULT InvokeEvent(DISPID id, TVariant* params)
  {
      if ((id == 1) && (FOnNewMessage!= NULL))         FOnNewMessage(params[0]);
      else if ((id == 2) && (FOnChangeStatus != NULL)) 
        FOnChangeStatus(params[0],params[1]);
   ...
      return S_OK;
  }

  CComPtr<IUnknown> m_pSender;

public:
  __property  TNewMessageEvents  OnNewMessage  =
    { read = FOnNewMessage, write = FOnNewMessage };

  __property TChangeStatusEvents OnChangeStatus =
    { read = FOnChangeStatus, write = FOnChangeStatus };
...
public:
  TnOTCRemouteSink() :
     m_pSender(NULL),
     FOnNewMessage(NULL),
     FOnChangeStatus(NULL)
     
  {
  }

  virtual ~TnOTCRemouteSink()
  {
     Disconnect();
  }

    void Connect(IUnknown* pSender)
  {
     if (pSender != m_pSender)
        m_pSender = pSender;
     if (NULL != m_pSender)
       ConnectEvents(m_pSender);
  }

  void Disconnect()
  {
    if (NULL != m_pSender)
    {
      DisconnectEvents(m_pSender);
      m_pSender = NULL;
    }
  }
};

#endif
И в своем приложении пишешь примерно следующий код:
Код:
 TCOMInOTCRemouteModule m_remoute;//Твой сервер уведомлений
TnOTCRemouteSink RMSick;//
...
Srvnotc_tlb::ConOTCRemouteModule::CreateRemote(WideString("you_host"),m_remoute);
RMSick.OnNewMessage = TgfmMain::OnNewMessage;
RMSick.OnChangeStatus = TgfmMain::OnChangeStatus;
...
RMSick.Connect(m_remoute);
m_remoute->GetMessageEm(&myid);
//////////////На сервере функция GetMessage определяется примерно так:
....
STDMETHODIMP TnOTCRemouteModuleImpl::GetMessageEm(long id){
 fmMain->GetMessageEmp(id);
 return S_OK;
}
....
///
void __fastcall TfmMain:: GetMessageEmp(long id){
 int Index  = GetRecordIndexById(id);
//employeeV - ето вектор структур TEmployee - которые содержат инфу о подключенных в данный момент юзерах - заполняется в функции Login.
//Соответсвенно GetRecordIndexById(id) - возвращает индекс в векторе по иду пользователя. 
//employeeV[Index].dm - указатель на датамодуль,employeeV[Index].ra - указатель на интерфейс сервера
//все это опять же инициализируется при логине.
// Можно реализовать это все гораздо проще - или сложней :)
 if(employeeV[Index].dm->adoGetMessage->Active)employeeV[Index].dm->adoGetMessage->Active = false;
 employeeV[Index].dm->adoGetMessage->Parameters->ParamByName("@id")->Value = id;
 employeeV[Index].dm->adoGetMessage->Active = true;
if(employeeV[Index].dm->adoGetMessage->RecordCount)
 employeeV[Index].ra->Fire_OnNewMessage(employeeV[Index].id);
//Если есть новые сообчения - генерим событие.

}
Надеюсь как обработать событие на клиенте - писать не надо?
Ну вот в принципе и все. Просто у меня сервер решает более сложные задачи, которые может быть в твоем случае и на.х не нужны - и работа с базой у меня тоже идет через него. По этому я не расписывал функции логирования на сервер - главное - ты должен создать объект пользователя, приципить к нему уникальный ид и привязать ссылки на дм и рдм. И соответственно при дисконнекте - это все освободить. Да - еще это предполагает что ты пользуешься моделью взаимодействия фри - при аппартменте возможно будет гораздо проще - просто на каждого юзера будет стартовать сое приложение.
__________________
kot_ вне форума  

Опции темы

Ваши права в разделе
Вы НЕ можете создавать новые темы
Вы не можете отвечать в темах.
Вы НЕ можете прикреплять вложения
Вы НЕ можете редактировать свои сообщения

BB код Вкл.
Смайлы Вкл.
[IMG] код Выкл.
HTML код Выкл.

Быстрый переход


Часовой пояс GMT +4, время: 08:53.




Powered by vBulletin® Version 3.8.5
Copyright ©2000 - 2025, Jelsoft Enterprises Ltd.