Форум » LetoDB, HbNetio. » Leto DB Server(продолжение) » Ответить

Leto DB Server(продолжение)

alkresin: Только что открыл на Sourceforge новый проект - Leto DB Server - https://sourceforge.net/projects/letodb Это мультиплатформенный ( Windows, Unix/Linux ) сервер баз данных, предоставляющий клиентским программам доступ к dbf/cdx файлам, находящимся на удаленном сервере ( можно и на локальном компьютере запускать - в отладочных целях ). В общем, как ADS :). Проект - на стадии разработки, не все даже базовые функции еще реализованы, до оптимизации дело еще не дошло. Но работает :). Крутится у меня на сервере несколько дней, подключал до 15 клиентов, пока не падает. Мои программы работают с ним нормально. Преимущества по сравнению с обычным файл-сервером: 1) Безопасность - базы могут быть в каталоге, недоступном для клиентских компьютеров - никто их случайно не удалит и не повредит. 2) Поскольку базы открываются серверной программой, а не клиентской, ее целостности ничего не грозит при случайном отключении клиентского компьютера. 3) значительное уменьшение сетевого траффика. 4) Должен быть, по идее, выигрыш в скорости. 5) Возможность контроля за пользователями с помощью утилиты manage ( можно придумать и другие формы контроля ). 6) Можно будет сделать транзакции, stored procedures на Харборе, ... и вообще все в наших руках :). Кто хочет участвовать в разработке, тестировании - пишите.

Ответов - 301, стр: 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 All

Pasha: PSP пишет: А как объяснить, что вьювер тоже не видит изменений? То, что вьювер вообще получает доступ к таблице, открытой letodb, говорит нам, что letodb работает в режиме Share_Tables. Это неэффективный режим, в режиме монопольного доступа letodb работает лучше. А обьяснение простое. Сервер letodb - это тот же dbfcdx. А как известно, путь от простого dbCommit к физической записи данных на диск труден и долог. Сначала dbfcdx сбрасывает эти данные в буфер операционки. А уж когда она соизволит их записать на диск - можно только догадываться. И лишь после этого их сможет увидеть вьювер. Который, кстати, тоже может не сразу обновить данные, у него может свой буфер имеется.

PSP: Pasha пишет: letodb работает в режиме Share_Tables Нет. Я специально в ini-файле даже Share_Tables = 0 поставил. У меня тоже такая мысль была. По идее сервер не должен давать доступ.

PSP: Pasha пишет: Который, кстати, тоже может не сразу обновить данные, у него может свой буфер имеется Я его многократно открываю-закрываю. Результат одинаковый.


PSP: Сейчас попробовал в файл-серверном варианте с DBFCDX. Две станции пишут по-очереди в одно поле одной записи. При этом не используется ни DBCommit(), ни сдвиг указателя записи. Только Lock и UnLock. Причем, содержимое поля читается и перед записью, и после. Так вот, данные читаются всегда актуальные, на обеих станциях. Так, собственно, и Клиппер работает.

PSP: Pasha пишет: Тоже самое касается и sql. Это стандартый вопрос: почему после транзакции другие клиенты ее не видят. И на это есть стандартный ответ: представьте, что после каждой транзакции sql-сервер вдруг начнет плеваться данными на всех подключенных в этот момент клиентов... это же нехорошо ? Вот поэтому клиенты должны сами, того, как тот Магомед, идти к горе. Паша, извините за позднюю реакцию, диагональное чтение... На это могу сказать одно: если после завершения транзакции SQL-сервер не вернет клиенту актуальные данные, разве это нормально? У меня именно такая ситуация. Транзакция закончена, клиент запрашивает данные и получает... устаревшие. Разве клиент должен заботиться об актуальности данных на сервере?

Pasha: Нет конечно. После завершения транзакции все запрашиваемые данные должны быть актуальны. Разве в letodb не так ? Я говорил о том, что уже полученные клиентом данные могут быть неактуальны, и после транзакции с другого клиента надо повторить запрос

PSP: Pasha пишет: Разве в letodb не так ? У меня получается, что "не так". Даже после завершения транзакции одной станцией, другая получает устаревшие данные. Проверял на двух серверах: под Ubuntu и под XP. Причем файл-серверный вариант (см.выше) нормально работает.

Pasha: PSP пишет: У меня получается, что "не так". Тогда разбираемся более предметно. t1.prg: Field Code, Name Function main Local cPath := '//127.0.0.1:2812/', nKey := 0 REQUEST LETO RDDSETDEFAULT( "LETO" ) cls dbCreate(cPath + 'test', {{'Code','N',2,0},{'Name','C',20,0}}) use (cPath + 'test') shared new dbAppend() dbCommit() while nKey # 27 rlock() leto_BeginTransaction() Field->Code ++ dbCommit() leto_CommitTransaction() dbUnlock() ? 'Client 1', Recno(), Field->Code wait nKey := LastKey() enddo return nil t2.prg: Field Code, Name Function main Local cPath := '//127.0.0.1:2812/', nKey := 0 REQUEST LETO RDDSETDEFAULT( "LETO" ) cls use (cPath + 'test') shared new while nKey # 27 goto 1 ? 'Client 2', Recno(), Field->Code wait nKey := LastKey() enddo return nil Запускам t1, выполняем первую транзакцию, выводим значение поля после транзакции Запускаем t2 - видим то же значение Переключаемся на t1, выполняем следующую транзакцию, переключаемся на t2 - видим то же самое значение. И так далее Получается что "так" Где собака порылась ?

PSP: С "goto 1" все "так". А без него "нет так". А теперь тот же пример, но без Leto, через DBFCDX. Исключаем "goto 1" - все работает "так". Даже без dbCommit(). В чем прикол? Почему драйвер DBFCDX позволят другой станции без сдвига указателя прочитать актуальные данные, а выполнение leto_CommitTransaction() не позволяет? Извините за нудность, просто налетел на эту фичу на рабочей базе. Кстати, в версиях Leto начала 2010 года (точно не скажу, не сохранилось), все работало "так" и без "goto". :)

Pasha: PSP пишет: С "goto 1" все "так". А без него "нет так". Без goto данные на 2-м клиенте не обновляются. Первый раз клиент 2 выдал запрос серверу на 1-ю запись и получил ее. Затем в цикле он, не запрашивая обновленные данные, выводит то значение, которое он получил первый раз, то есть необновленное. Как вы себе представляете, клиентская программа должна сама по себе без пинка запрашивать обновленные данные с сервера ? Чтобы обновить запись, надо либо сместить указатель текущей записи и вернуться на нужную, либо выдать dbgoto(recno()) или dbskip(0). Правда, в лето есть еще механизм кеширования skip, но здесь он не работает, не будем усложнять.

Pasha: Вот пример без лето и без goto t1.prg Field Code, Name Function main Local cPath := '', nKey := 0 cls dbCreate(cPath + 'test', {{'Code','N',2,0},{'Name','C',20,0}}) use (cPath + 'test') shared new dbAppend() dbCommit() while nKey # 27 rlock() Field->Code ++ dbCommit() dbUnlock() ? 'Client 1', Recno(), Field->Code wait nKey := LastKey() enddo return nil t2.prg Field Code, Name Function main Local cPath := '', nKey := 0 cls use (cPath + 'test') shared new while nKey # 27 // goto 1 ? 'Client 2', Recno(), Field->Code wait nKey := LastKey() enddo return nil И что мы видим: да никакой мистики с фантастикой, 2-й клиент видит необновленные данные. Все работает, как и должно работать

PSP: Pasha пишет: Как вы себе представляете, клиентская программа должна сама по себе без пинка запрашивать обновленные данные с сервера ? Чтобы обновить запись, надо либо сместить указатель текущей записи и вернуться на нужную, либо выдать dbgoto(recno()) или dbskip(0). Я всегда думал, что выдача актуальных данных - забота сервера. Клиент вправе считать полученные данные актуальными в любой момент времени и не знает, когда ему нужно сдвинуть указатель, а когда не нужно. Тем более, если указатель уже находится на нужной записи. Ладно, вопрос можно считать закрытым. Паше спасибо за терпение. :)

Pasha: PSP пишет: Я всегда думал, что выдача актуальных данных - забота сервера. Единственная забота сервера - обслужить клиента, т.е обработать его запрос. Сервер сам по себе клиенту ничего не посылает. Если бы это было так, то это был бы не клиент-сервер, а сервер-сервер. На стороне клиента пришлось бы делать какой-то диспетчер запросов, принимать команды с сервера...

PSP: Да уж... Развил я тут тему... :) Паша, еще раз спасибо за терпение.

Dimka: как letodb сейчас работает на многоядерных системах?

Pasha: Dimka пишет: как letodb сейчас работает на многоядерных системах? В letodb используется 2 потока. Значит, будет работать как обычное многопоточное приложение. Я специально не исследовал этот вопрос, но думается, что каждое ядро будет выполнять отдельный поток

Pasha: Добавил новую функцию: Leto_Commit() Она заменяет вызовы: dbCommit() dbUnlock() Обычно клиент посылает серверу 3 пакета : для обновления записи, для commit и для unlock Новая функция посылает только один пакет для всех этих операций. Таким образом, при обновлении данных количество пакетов можно уменьшить втрое

Andrey: Pasha пишет: Таким образом, при обновлении данных количество пакетов можно уменьшить втрое Классное решение ! Спасибо за рацпредложение и исполнение его !

Dimka: пытаюсь начать пользоваться letodb. на одном большом рассчете программка начинает течь и занимает 1гб оперативы и более. успокойте меня, скажите что это изза того, что используются индексы NTX. и команда USE делает последний из перечисленных индексов активным.

Pasha: Dimka пишет: успокойте меня, скажите что это изза того, что используются индексы NTX. и команда USE делает последний из перечисленных индексов активным. Фантазировать мы не будем. Лучше попробуйте выяснить, какое действие является причиной протечки. Очень уж воды много выливается. У меня вот приличная по размеру программа занимает всего 12М, а тут целый гектар, впечатляет.



полная версия страницы