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

Вниз

Многопользовательский доступ к БД   Найти похожие ветки 

 
saNat ©   (2008-04-15 09:24) [0]

Доброго времени суток, Мастера (о:

Подскажите, пожалуйста, по следующей проблеме.
Есть некая БД на Access, расположенная в папке с общим доступом с правами на чтение/запись. Есть приложение "просмотрщик" данных, которое с определенным интервалом времени считывает информацию, а так же "редактор" данных, посредством которого информация в базу заносится. Приложения написаны на Delphi 6. Соединение устанавливается посредством ADO (MS Jet 4.0 OLE DB Provider). Суть проблемы: невозможна одновременная работа нескольких пользователей: получаю ошибку подключения к БД. Подскажите, пожалуйста, что дополнительно нужно указывать в строке подключения, или ткните носом, где почитать.

С уважением, ЕВА.


 
Виталий Панасенко(дом)   (2008-04-15 10:00) [1]

Может, настроен эксклюзивный доступ ?


 
saNat ©   (2008-04-15 10:03) [2]

По-умолчанию стоит "Share Deny None". Если я правильно читал, то это отсутствие блокировки записи/чтения. Или я не прав?


 
sniknik ©   (2008-04-15 10:30) [3]

> что дополнительно нужно указывать в строке подключения
желательно ничего... чем меньше значений и так по умолчанию устанавливаемых тем меньше вероятность ошибок.
по умолчанию должно работать.

> с правами на чтение/запись.
а на редактирование? а то впечатление такое, что файл блокировок первым коннектом создается, а у следующего нет прав его изменить (вписать себя)... о и получает тода минимальные. толко на чтение.


 
saNat ©   (2008-04-15 10:53) [4]

Гм... Так и есть. А Вы не п\могли бы подсказать где поправить (прочитать)?


 
saNat ©   (2008-04-15 11:11) [5]

Возможно, следует сказать, что к общей папке дан полный доступ.


 
saNat ©   (2008-04-15 14:07) [6]

Вообщем удалось обнаружить такую деталь: "блокирование" происходит в том случае, если приложение подсоединяется к "локальной базе по сети". Т.е. если запустить приложение на компьютере с установленной БД, указав "сетевой путь" (\\MyPC\MyApp\MyDB.mdb), то с клиентских машин соединение не уставнавливается. Если же запускать "локально" (C:\MyApp\MyDB.mdb), то клиентские машины успешно подключаются.
Я понимаю, что глупо на локальной машине указывать сетевой путь, но вдруг пользователь "ткнет". К тому же это наблюдение, которое я пока не могу обосновать, грубо говоря, не могу сказать "не суй пальцы в мясорубку, потому что их отрежет ножом".

Может кто-нибудь дать направление для размышлений?

С уважением, ЕВА


 
saNat ©   (2008-04-15 14:18) [7]

Возможно (хотя что тут смотреть) требуется код...
Кнопка подключения к БД:

Procedure TDeskTop.TestButtonClick(Sender:TObject);
Begin
DBModule.DBPath:="\\B0000011\Base\DBase.mdb";
// DBModule.DBPath:="D:\test\DBase.mdb";
DBModule.DBConnect:=True;
If DBModule.DBConnect
 Then
  TestButton.Caption:="Офигеть! Соединение установлено."
 Else
  TestButton.Caption:="Не работает...";
End;

dataModule для тестов с базой:

Unit DBModuleUnit;

Interface

Uses
ADODB,Classes,DB,SysUtils;

Type
TDBModule=Class(TDataModule)
  DBConnection                                         :TADOConnection;
  Procedure DataModuleCreate(Sender:TObject);
  Procedure DBConnectionBeforeConnect(Sender:TObject);
 Private
  FDBPath                                              :String;
  Function GetDBConnect:Boolean;
  Procedure SetDBConnect(Value:Boolean);
  Procedure SetDBPath(Value:String);
 Public
 Published
  Property DBConnect:Boolean
   Read GetDBConnect
   Write SetDBConnect;
  Property DBPath:String
   Read FDBPath
   Write SetDBPath;
End;

Var
DBModule                                               :TDBModule;

Implementation

{$R *.dfm}

Procedure TDBModule.DataModuleCreate(Sender:TObject);
Begin
FDBPath:="";
End;

Procedure TDBModule.DBConnectionBeforeConnect(Sender:TObject);
Begin
DBConnection.ConnectionString:="Provider=Microsoft.Jet.OLEDB.4.0;"+
                               "Data Source=""+DBPath+"";"+
                               "Persist Security Info=False;"+
                               "Jet OLEDB:Database Password=001007326";
End;

Function TDBModule.GetDBConnect:Boolean;
Begin
Result:=DBConnection.Connected;
End;

Procedure TDBModule.SetDBConnect(Value:Boolean);
Begin
Case Value Of
  True: Begin
         DBConnection.Connected:=False;
         DBConnection.Connected:=True;
        End;
 False: DBConnection.Connected:=False;
End;
End;

Procedure TDBModule.SetDBPath(Value:String);
Begin
FDBPath:=Value;
End;

End.


 
sniknik ©   (2008-04-15 14:43) [8]

> указав "сетевой путь" (\\MyPC\MyApp\MyDB.mdb)
> запускать "локально" (C:\MyApp\MyDB.mdb)

> DBModule.DBPath:="\\B0000011\Base\DBase.mdb";
> // DBModule.DBPath:="D:\test\DBase.mdb";

не равнозначно, если конечно там не алиас в расшарке, но пока вывод - по сути делается одно, а интерпритация по несуществующему варианту... т.е. "вывод по кофейной гуще".


 
saNat ©   (2008-04-15 14:56) [9]

> указав "сетевой путь" (\\MyPC\MyApp\MyDB.mdb)
> запускать "локально" (C:\MyApp\MyDB.mdb)

В данном случае абстрактный пример. Попробую на конкретном...
Итак, на 1 машине по адресу "D:\Test\DBase.mdb" лежит БД. В сети она видна как "\\B0000011\Base\DBase.mdb".
1. Если на первой машине приложение соединяется к БД с прописанным путем "D:\Test\DBase.mdb", то другие клиенты (в сети; подключаются к "\\B0000011\Base\DBase.mdb") соединяются к БД успешно.
2. Если на первой машине приложение соединяется к БД с прописанным путем "\\B0000011\Base\DBase.mdb", то другие клиенты (в сети; подключаются к "\\B0000011\Base\DBase.mdb") не соединяются с БД. Получаю ошибку "Невозможно использовать "; файл уже используется".
3. Если сначала к БД подключился клиент (в сети; подключаются к "\\B0000011\Base\DBase.mdb"), а потом присоединяется 1 машина (так же к "\\B0000011\Base\DBase.mdb"), то соединение успешно.

Т.е. подключаясь с "сети" 1 машина создает файл подключений, который недоступен клиентам? Вот все пока что могу придумать. А как обойти даже не знаю.

С уваженем, ЕВА


 
saNat ©   (2008-04-15 14:57) [10]


> 2. Если на первой машине приложение соединяется к БД с прописанным
> путем "\\B0000011\Base\DBase.mdb", то другие клиенты (в
> сети; подключаются к "\\B0000011\Base\DBase.mdb") не соединяются
> с БД. Получаю ошибку "Невозможно использовать "; файл уже
> используется".


Поправлюсь: "выдают ошибку"


 
sniknik ©   (2008-04-15 15:16) [11]

> В данном случае абстрактный пример.
перенести в потрепаться? абстракциям и флуду там самое место, а не сдесь.

> Итак, на 1 машине по адресу "D:\Test\DBase.mdb" лежит БД. В сети она видна как "\\B0000011\Base\DBase.mdb".
еще раз. пусть машина называется B0000011, согласен, но при расшаривании папки Test получить Base без указания его алиасом невозможно. про алиас ты не упоминал... вывод? ты подключаешься к разным базам, а вывод делаешь как будто работаешь с одной. при разных естественно никаких проблем у разных коннектов.

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

> Вот все пока что могу придумать.
сам смотри в файл блокировок, блокнотом, и проверяй создаются там записи при каждом подключении или нет.


 
saNat ©   (2008-04-15 15:22) [12]


> еще раз. пусть машина называется B0000011, согласен, но
> при расшаривании папки Test получить Base без указания его
> алиасом невозможно. про алиас ты не упоминал... вывод? ты
> подключаешься к разным базам, а вывод делаешь как будто
> работаешь с одной. при разных естественно никаких проблем
> у разных коннектов.

Да, конечно, используется алиас. Чтобы исключить все возможные недопонимания, уточню: открывая общий доступ к папке "D:\Test\" в поле "Общий ресурс" введено значение "Base". В разрешениях для всех ("Все") дан полный доступ ("Полный доступ").


 
sniknik ©   (2008-04-15 15:33) [13]

тогда еще вариант. у XP ограничение на 10 коннектов извне по сети, допустим 9 у тебя уже чемто/кемто занято... тогда подключение самого к себе тоже вроде как внешнее занимает последний "слот". дальнейшие ведут к отказам -Ю ошибкам подключения.  

в этом случае у тебя в event-сах (eventvwr.msc) будет полно ошибок типа TCP - превышен лимит на подключения (точность формулировки не гарантирую)... если найдешь такие, то выход перенести базу на серверную систему, у которой нет подобных ограничений . или "проредить" существующие. (есть еще хакерский вариант, но не будем об этом...)


 
saNat ©   (2008-04-16 10:03) [14]

sniknik ©, прошу прощения, я все таки обнаружил ситуацию описанную в  [11]. Окончательно запутавшись, решил выделить кусок соединения клиента к БД. Итак.

1. Проект находится по адресу: "D:\DelphiN\Проекты\КаДР\v. 1.1\Управление доступом"
2. База данных находится по адресу: "D:\DelphiN\Проекты\КаДР\v. 1.1\Base"
3. База данных видна в локальной сети: "\\B0000011\Base"
4. Имя файла базы данных: "DBase.mdb"
5. К "\\B0000011\Base" открыт полный доступ

DeskTopUnit - главная форма:

Unit DeskTopUnit;

Interface

Uses
Classes,Controls,DBModuleUnit,DBPathUnit,Dialogs,Forms,Graphics,Menus,Messages,
StdCtrls,SysUtils,Variants,Windows;

Type
TDeskTop=Class(TForm)
  TestButton                                           :TButton;
  AppMenu                                              :TMainMenu;
   N1                                                  :TMenuItem;
   N2                                                  :TMenuItem;
   N3                                                  :TMenuItem;
   N4                                                  :TMenuItem;
  Procedure TestButtonClick(Sender:TObject);
   procedure N2Click(Sender: TObject);
 Private
 Public
End;

Var
DeskTop                                                :TDeskTop;

Implementation

{$R *.dfm}

Procedure TDeskTop.TestButtonClick(Sender:TObject);
Begin
Try
 DBModule.DBConnect:=Not DBModule.DBConnect;
 If DBModule.DBConnect
  Then
    TestButton.Caption:="РАЗОРВАТЬ СОЕДИНЕНИЕ"
  Else
    TestButton.Caption:="НА ЖМИ МЕНЯ";
Except
 MessageDlg("А ВОТ ТЕБЕ, РОЖА БУРЖУЙСКАЯ, ДУЛЯ ПРОЛЕТАРСКАЯ!",mtError,[mbOK],0);
End;
End;

Procedure TDeskTop.N2Click(Sender: TObject);
Begin
DBPath.ShowModal;
End;

End.


DBModule - операции с базой данных:

Unit DBModuleUnit;

Interface

Uses
ADODB,Classes,DB,DBPathUnit,SysUtils;

Type
TDBModule=Class(TDataModule)
  DBConnection                                         :TADOConnection;
  DBQuery                                              :TADOQuery;
  Procedure DBConnectionBeforeConnect(Sender:TObject);
 Private
  Function GetDBConnect:Boolean;
  Procedure SetDBConnect(Value:Boolean);
 Public
  Property DBConnect:Boolean
   Read GetDBConnect
   Write SetDBConnect;
End;

Var
DBModule                                               :TDBModule;

Implementation

{$R *.dfm}

Procedure TDBModule.DBConnectionBeforeConnect(Sender:TObject);
Var
 Buffer                                                :String;
Begin
DBConnection.ConnectionString:="Provider=Microsoft.Jet.OLEDB.4.0;"+
                               "Data Source="+DBPath.DBPath+";"+
                               "Persist Security Info=False;"+
                               "Jet OLEDB:Database Password=0322907";
End;

Function TDBModule.GetDBConnect:Boolean;
Begin
Result:=DBConnection.Connected;
End;

Procedure TDBModule.SetDBConnect(Value:Boolean);
Begin
Case Value Of
  True: Begin
         If DBConnection.Connected
          Then
            DBConnection.Close;
         DBConnection.Open;
        End;
 False: DBConnection.Close;
End;
End;

End.


DBPathUnit - параметры приложения

Unit DBPathUnit;

Interface

Uses
Classes,Controls,Graphics,Forms,Dialogs,Mask,Messages,
rxToolEdit,StdCtrls,SysUtils,Variants,Windows;

Type
TAppSettings=Record
 DBPath                                                :String[255];
 DayCount                                              :Integer;
End;
TDBPath=Class(TForm)
  DBPathHint                                           :TLabel;
  DBPathValue                                          :TFilenameEdit;
  ButtonSave                                           :TButton;
  ButtonClose                                          :TButton;
   procedure FormCreate(Sender: TObject);
   procedure FormActivate(Sender: TObject);
   procedure ButtonSaveClick(Sender: TObject);
   procedure ButtonCloseClick(Sender: TObject);
 Private
  Function GetDBPath:String;
  Procedure SetDBPath(Value:String);
 Public
  Property DBPath:String
   Read GetDBPath
   Write SetDBPath;
End;

Var
DBPath                                                 :TDBPath;

Implementation

{$R *.dfm}

Procedure TDBPath.FormCreate(Sender:TObject);
Begin
DBPathValue.Text:="";
DBPathValue.InitialDir:=ExtractFilePath(ParamStr(0));
DBPathValue.HistoryList.Clear;
DBPathValue.FileName:="";
DBPathValue.DefaultExt:="";
End;

Procedure TDBPath.FormActivate(Sender:TObject);
Begin
DBPathValue.InitialDir:=ExtractFilePath(ParamStr(0));
DBPathValue.HistoryList.Clear;
DBPathValue.DefaultExt:="";
DBPathValue.FileName:=DBPath;
End;

Procedure TDBPath.ButtonSaveClick(Sender:TObject);
Begin
DBPath:=DBPathValue.FileName;
ModalResult:=mrOk;
End;

Procedure TDBPath.ButtonCloseClick(Sender:TObject);
Begin
ModalResult:=mrCancel;
End;

Function TDBPath.GetDBPath:String;
Var
 FileSettings                                          :File Of TAppSettings;
 AppSettings                                           :TAppSettings;
Begin
AssignFile(FileSettings,ExtractFilePath(ParamStr(0))+"\Settings.cfg");
{$I-}
ReSet(FileSettings);
{$I+}
If IOResult=0
 Then
  Begin
   Read(FileSettings,AppSettings);
   CloseFile(FileSettings);
   Result:=AppSettings.DBPath;
  End
 Else
  Begin
   MessageDlg("Файл конфигурации отсутствует или поврежден.",mtWarning,[mbOk],0);
   Result:="";
  End;
End;

Procedure TDBPath.SetDBPath(Value:String);
Var
 FileSettings                                          :File Of TAppSettings;
 AppSettings                                           :TAppSettings;
Begin
AssignFile(FileSettings,ExtractFilePath(ParamStr(0))+"\Settings.cfg");
{$I-}
ReSet(FileSettings);
{$I+}
If IOResult=0
 Then
  Begin
   Read(FileSettings,AppSettings);
   CloseFile(FileSettings);
  End
 Else
  Begin
   AppSettings.DBPath:="";
   AppSettings.DayCount:=1;
  End;
AppSettings.DBPath:=Value;
{$I-}
ReWrite(FileSettings);
{$I+}
If IOResult=0
 Then
  Begin
   Write(FileSettings,AppSettings);
   CloseFile(FileSettings);
  End
 Else
   MessageDlg("Ошибка записи файла конфигурации.",mtError,[mbOk],0);
End;

End.


Проблема:
1. Если первым подключается сервер (ПК, на котором находится БД), то клиент не подключается
Файл блокировок:

B0000011                        Admin                          

2. Если подключается клиент, а потом сервер, то соединение устанавливается у всех корректно.
Файл блокировок:

B0000067                        Admin                           B0000011                        Admin                          


На результат не влияет задаваемый на сервере путь к базе данных ("сетевой" или "локальный").

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

С уважением, ЕВА.


 
saNat ©   (2008-04-16 10:11) [15]

Еще раз перечитал вышенаписанное. Проверил такой момент:
1. Подключился к БД с сервером
2. Изменил правила безопасности для файла блокировок DBase.ldb, добавив пользователя "Все" с праввми "Изменить/Чтение и выполнение/Чтение/Запись".
3. Подключился к БД клиентом.

Файл блокировок:

B0000011                        Admin                           B0000067                        Admin                          


Т.е. можно сделать вывод, как правильно заметил sniknik, проблема в файле блокировок (посыпаю голову пеплом, ибо про то написали почти сутки назад). Как можно ее решить, если он (файл блокировок) каждый раз создается заново?


 
sniknik ©   (2008-04-16 10:46) [16]

проблема не в файле блокировок, он то как раз честно делает то, что должен, и то что ему разрешили... проблема в правах. ("обратитесь к администратору сети")
а почему у тебя файл с разными юзерами(методами подключения) создается с разными разрешениями, которые по идее они должны наследоваться от папки, на которую говоришь стоит все... х.з. привлекай админа.


 
saNat ©   (2008-04-16 10:52) [17]


> проблема не в файле блокировок, он то как раз честно делает
> то, что должен, и то что ему разрешили... проблема в правах.
>  

Да, конечно. Я неверно выразился.

> а почему у тебя файл с разными юзерами(методами подключения)
> создается с разными разрешениями, которые по идее они должны
> наследоваться от папки, на которую говоришь стоит все...
>  х.з. привлекай админа.

В разрешениях папки по-умолчанию) прописаны пользователи:
1. SYSTEM
2. Администраторы (B0000011\Администраторы)
3. Пользователи (B0000011\Пользователи)
4. <Моя учетная запись>
5. СОЗДАТЕЛЬ-ВЛАДЕЛЕЦ

Владельцем являются:
1. Администраторы (B0000011\Администраторы)
2. <Моя учетная запись>

Правильным ли решением будет добавить "Все" с правами на, грубо говоря, чтение/запись/изменение?


 
saNat ©   (2008-04-16 11:07) [18]

Подразумевается - правильным решением, т.к. добавив указанное выше разрешение проблема исчезла.


 
sniknik ©   (2008-04-16 11:15) [19]

> На результат не влияет задаваемый на сервере путь к базе данных ("сетевой" или "локальный").
о... а говорил влияет, и различается лиш способом подключения.
тогда возможно все проще (нет неоднозначности "подключение > другой юзер"). на сервере просто прогу запускают от админа и созданный ей файл получает его владельцем, "гостям" править такой файл в разрешениях не выставлено. с обратной ситуацией, файл во владельцах имеет "гостя", такой правят все кому не лень админ тоже. и вся "загадка".
но тогда получается ты обманывал когда говорил что
> расположенная в папке с общим доступом с правами на чтение/запись.
общих("все") прав там нет.


 
sniknik ©   (2008-04-16 11:17) [20]

saNat ©   (16.04.08 10:52) [17]
ну вот, подтверждение ([19]) раньше чем запостил...


 
saNat ©   (2008-04-16 11:24) [21]

Чаще всего про "Все" вспоминать не приходилось, потому и заблуждался о "полном доступе". Думаю, вопрос решен.
sniknik ©, большое спасибо за уделенное внимание и помошь (о:

С уважением, ЕВА.



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

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

Наверх





Память: 0.56 MB
Время: 0.007 c
15-1220006168
Prohodil Mimo
2008-08-29 14:36
2008.10.19
JavaScript


3-1208167098
Виталий Панасенко(дом)
2008-04-14 13:58
2008.10.19
select from select в FireBird 2.0.1/2.1


2-1220825497
dars73
2008-09-08 02:11
2008.10.19
Подскожите пожалуйста почему я не могу подключить модуль


15-1219934803
kaif
2008-08-28 18:46
2008.10.19
Кто-нибудь может перевести?


15-1220035565
Terasbetoni
2008-08-29 22:46
2008.10.19
Книга "Валерий Фаронов - Искусство создания компонентов Delphi"





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
Английский Французский Немецкий Итальянский Португальский Русский Испанский