Автор | Сообщение |
|
| |
Пост N: 1
Зарегистрирован: 08.12.06
|
|
Отправлено: 08.12.06 12:00. Заголовок: Работа индексов в многопользовательском режиме
Подскажите новичку, могут ли возникнуть какие-нибудь коллизии, если несколько пользователей будут в сети открывать базы с индексами и модифицировать данные одновременно вот таким способом: use bma02 alias b share index on str(SAW,2)+str(NP,3) to BMA02 set index to BMA02 т.е. сразу индексировать в один и тотже файл или индексный файл также работает как база в shared режиме или лучше чтоб для каждого пользователя в сети индексы создавались на локальной рабочей станции?
|
|
|
Ответов - 14
[только новые]
|
|
|
| постоянный участник
|
Пост N: 143
Зарегистрирован: 12.09.06
|
|
Отправлено: 08.12.06 12:24. Заголовок: Re:
Индексировать базы одновременно нельзя ! Лучше индексировать базу в монопольном режиме и одним человеком, выгоняя всех остальных из этой базы или программно или "криком-всем вон из программы". А вносить исправления в базу все могу спокойно, так как сам драйвер индекса отслеживает изменение записей.
|
|
|
|
| |
Пост N: 2
Зарегистрирован: 08.12.06
|
|
Отправлено: 08.12.06 12:57. Заголовок: уточнение
Т.е. вот, например, один пользователь запустил программу, открылась база, проиндексировалась, он стал вносить в неё данные, удалил несколько записей, в этот момент другой пользователь запускает программу, она открывает базу и начинает индексировать в тот же файл, что и первый. После этого первый пользователь добавляет новые записи, как в такой ситуации будет использоваться индексный файл, он свои добавленные записи увидит? Или при такой работе будут потери данных?
|
|
|
|
| модератор
|
Пост N: 368
Зарегистрирован: 25.05.05
|
|
Отправлено: 08.12.06 14:52. Заголовок: Re:
SKA, Попробуй использовать идею из следующего кода: цитата: | If !File( Path_data+"MAIN.DBF" ) DBcreate( Path_data+"MAIN.DBF", aStruct ) EndIF USE ( Path_data+"MAIN" ) ALIAS MAIN SHARED NEW If !NetErr() If !File( ( Path_data+"MAIN"+INDEXEXT() ) ) INDEX ON MAIN->NAME TO ( Path_data+"MAIN_IDX" ) DBcommit() EndIF SET INDEX TO ( Path_data+"MAIN_IDX" ) Else MsgStop("Database MAIN in use", "Please, try again") return nil EndIF |
|
|
|
|
|
| |
Пост N: 54
Зарегистрирован: 08.04.06
|
|
Отправлено: 09.12.06 04:05. Заголовок: Re:
Насколько я помню, базы по USE по умолчанию открываются как SHARED и указывать это явным образом не обязательно. Фрагмент MsgStop("Database MAIN in use", "Please, try again") return nil надо заменить на SET INDEX TO ( Path_data+"MAIN_IDX" ) то есть открывать индекс нужно в любом случае - был ли он уже или создан только что пользователем, - у меня в программе по крайней мере именно так и сделано - все пользователи-клиенты открывают имеющиеся на главном компе базы и индексы и спокойно с ними работают. Вносимые записи тут же (ну или по DBCOMMIT() :-) появляются в списках. С удаляемыми записями сложнее - тут нужно или периодически пересвечивать объект TBrowse или перед работой с записью проверять поиском - а есть ли она ещё в базе или уже удалена.
|
|
|
|
| постоянный участник
|
Пост N: 72
Зарегистрирован: 09.10.06
|
|
Отправлено: 09.12.06 17:04. Заголовок: Re:
Лукашевский пишет: цитата: | Насколько я помню, базы по USE по умолчанию открываются как SHARED и указывать это явным образом не обязательно |
| Когда встречается команда USE без SHARED или EXCLUSIVE, базы данных открываются в соответствии с текущим состоянием SET EXCLUSIVE. По умолчанию SET EXCLUSIVE установлено в ON, т.е. все базы открываются в монопольном режиме. Лукашевский пишет: цитата: | Фрагмент MsgStop("Database MAIN in use", "Please, try again") return nil надо заменить на SET INDEX TO ( Path_data+"MAIN_IDX" ) |
| Не разобрались, ну и зачем Вам открывать индекс, если не удалось открыть базу? Лукашевский пишет: цитата: | то есть открывать индекс нужно в любом случае - был ли он уже или создан только что пользователем |
| А это правильно и gfilatov так и написал If !File( ( Path_data+"MAIN"+INDEXEXT() ) ) нет файла с индексом - создаем INDEX ON MAIN->NAME TO ( Path_data+"MAIN_IDX" ) DBcommit() EndIF SET INDEX TO ( Path_data+"MAIN_IDX" ) используем индекс в любом случае
|
|
|
|
| постоянный участник
|
Пост N: 147
Зарегистрирован: 12.09.06
|
|
Отправлено: 10.12.06 02:43. Заголовок: Re:
Народ, я с вами не согласен. Если нет индекса, то нельзя его делать, так как можно налететь на "грабли", а именно 2-станции будут создавать индекс. И кто тогда вылетит ? И создавать индекс должен кто-то ОДИН и в монопольном режиме открытия базы.
|
|
|
|
| |
Пост N: 505
Зарегистрирован: 17.05.05
|
|
Отправлено: 10.12.06 11:08. Заголовок: Re:
Andrey пишет: цитата: | Народ, я с вами не согласен. Если нет индекса, то нельзя его делать, так как можно налететь на "грабли", а именно 2-станции будут создавать индекс. И кто тогда вылетит ? И создавать индекс должен кто-то ОДИН и в монопольном режиме открытия базы. |
| Правильно говоришь. Тут может быть несколько подходов. 1. Например если индекса нет а он нужен то можно дальше пользователя не пускать............ 2. Можно первый раз при входе в программу (утром) проверять наличие этих самых индексов и создавать их + попутно можно делать упаковку и переиндексацию и на момент вот такого входа всех пользователей временно не пускать , пока не будет выполнен вот такой первый вход. лично я так и делаю ;) я о втором варианте.
|
|
|
|
| постоянный участник
|
Пост N: 75
Зарегистрирован: 09.10.06
|
|
Отправлено: 10.12.06 21:56. Заголовок: Re:
Andrey пишет: цитата: | Если нет индекса, то нельзя его делать, так как можно налететь на "грабли", а именно 2-станции будут создавать индекс. И кто тогда вылетит ? |
| А можно и не налететь. Ведь gfilatov пишет: "Попробуй использовать идею из следующего кода". Идею, а не код. Andrey пишет: цитата: | И создавать индекс должен кто-то ОДИН и в монопольном режиме открытия базы. |
| Команда SET INDEX не требует монопольного владения БД. Насчет кто-то ОДИН и Dima пишет: цитата: | Можно первый раз при входе в программу (утром) проверять наличие этих самых индексов и создавать их + попутно можно делать упаковку и переиндексацию и на момент вот такого входа всех пользователей временно не пускать |
| Это Вы скорее об администрировании БД и здесь действительно может быть несколько подходов, и REINDEX требует SET EXCLUSIVE ON. А вообще SKA каждый раз при открытии таблицы заново ее индексировать в многопользовательском режиме это слишком, если речь конечно не идет о вновь созданной базе или создании временного индекса, который будет через несколько строчек кода удален. Действительно индексный файл также работает как база в shared режиме, так что создайте его раз и позаботьтесь о поддержании его в актуальном состоянии.
|
|
|
|
| |
Пост N: 55
Зарегистрирован: 08.04.06
|
|
Отправлено: 11.12.06 02:37. Заголовок: Re:
Dima пишет: цитата: | Тут может быть несколько подходов. 1. Например если индекса нет а он нужен то можно дальше пользователя не пускать............ 2. Можно первый раз при входе в программу (утром) проверять наличие этих самых индексов и создавать их + попутно можно делать упаковку и переиндексацию и на момент вот такого входа всех пользователей временно не пускать , пока не будет выполнен вот такой первый вход. лично я так и делаю ;) я о втором варианте. |
| 3. Назначаем какой-нибудь комп "главным" (лучше, наверное, тот, на котором базы - индексы будут создаваться быстрее), и чтобы только он мог создавать индексы, и всех юзверей предупреждаем, что на этом компе программа должна быть запущена первой. А если индекса(ов) нет - то юзверей временно не пущать. 4. Нет индекса - открываем базу в монопольном режиме и делаем по ней индекс, потом переоткрываем в SHARED. Т.о. избавляемся от варианта попытки одновременного создания индексного файла - если базу в монополе открыть не удаётся - значит, её уже открыли в монополе и делают индекс с другого компа (станции), и тогда просто ждём, пока сделают.
|
|
|
|
| |
Пост N: 56
Зарегистрирован: 08.04.06
|
|
Отправлено: 11.12.06 02:50. Заголовок: Re:
Петр пишет: цитата: | Не разобрались, ну и зачем Вам открывать индекс, если не удалось открыть базу? |
| Согласен, извиняюсь, просто пример от gfilatov по-моему некорректный: базу в частном случае открываем и на главном компьютере тоже, на котором собственно база и лежит, и тогда !NetErr() скорее всего выдаст абы что - впрочем, утверждать не буду, я NetErr() вообще не использую...
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 01.01.70
|
|
Отправлено: 19.01.07 00:17. Заголовок: Re:
Создай индекс один раз, помести его с базой на сервере и пусть на каждой станции индексную базу цепляют так : use narod new index fam,nam,sna shared а далее используй set order to 1 или 2 или 3 Индексируй только в монопольном режиме в shared команда работать не будет. Если индекс будешь цеплять так, то никаких проблем с его актуальностью не испытаешь....
|
|
|
|
|
| постоянный участник
|
Пост N: 10
Зарегистрирован: 06.02.07
|
|
Отправлено: 12.02.07 18:32. Заголовок: Re:
И я так (как советует 15 лет в cliiper ) тоже делаю (при сетевой проге)! Коли валяется база с индексами (которые <b>должны</b> при ней быть) где-то на файл-серваке - то слепил индекс при очередной чистке-сжатии, а юзера уж пусть приходят "на готовенькое"! Вот разве что ему приспичит какой-то для себя "лично" (типа INDEX ... FOR ...) - так и это можно разрулить ("слив" для FOR в локальную времянку и т.п. подходы). А общее - не трожь!!! И проблем с актуальностью (если своевременые COMMITы делать) тоже не возникало ни разу за мнадцать лет (всякая там забивка больничных листов, поликлиничных посещений и т.п. - станций 40-50 одновременно - аж года с 92-го до последних времен фурычила на Netware-серваке без "фатальных" завалов).
|
|
|
|
| |
Не зарегистрирован
Зарегистрирован: 12.11.12
|
|
Отправлено: 12.11.12 14:44. Заголовок: Здравствуйте! Подска..
Здравствуйте! Подскажите, пожалуйста, про DBcommit() при индексировании. Выше в фрагменте: INDEX ON .. TO ... DBcommit() Это нужно для общего индекса на сервере?
|
|
|
|
| |
Пост N: 641
Зарегистрирован: 11.06.10
|
|
Отправлено: 12.11.12 17:20. Заголовок: Marry пишет: DBcomm..
Marry пишет: цитата: | DBcommit() Это нужно для общего индекса на сервере? |
|
Вкратце: dbcommit() служит для принудительного сброса данных с буфера на диск, во избежании пропадания данных, в сетевой среде делает видимыми данные для других процессов, к-е работают с этой базой. Если баз >1, то применяем dbcommitall(), одни раз для всех открытых баз.
|
|
|
|