LetoDB: ответы на вопросы,
которые возникают или могут возникнуть.
(Новые вопросы можно предложить в конце страницы)
- Где взять, как установить?
- Откуда такое название, почему LetoDB?
- Помогите разобраться в режимах работы сервера.
- Как работает кэширование записей, как его настраивать?
- Что надо изменить в программе, чтобы начать использовать LetoDB?
- Можно ли в одной программе работать с несколькими LetoDB серверами?
- Как правильно оформить транзакцию?
- В каких случаях использовать транзакции?
- Можно ли использовать LetoDB сервер из программ, написанных на C, Delphi и др. языках?
Где взять, как установить?
Проект LetoDB размещен на SourceForge, оттуда можно скачать дистрибутив с исходниками последней официальной сборки, можно получить самые свежие исходники с помощью Git:
git clone http://git.code.sf.net/p/letodb/codeили вот по этой ссылке, щелкнув по кнопке "Download snapshot".
Дистрибутивы с официальной сборкой, как с исходниками, так и некоторые бинарные, можно скачать и у меня на сайте на странице LetoDb.
Если вам не подойдут готовые бинарные дистрибутивы с моего сайта, вам придется скомпилировать
LetoDB самостоятельно. Это совсем не трудно, все подробно описано в readme_rus.txt
.
Можете воспользоваться или Харборовской утилитой Hbmk, или одним из bat-файлов,
входящих в состав дистрибутива. В этом последнем случае главное - указать системе, где находится
Harbour и, возможно, ваш С компилятор.
Если вы собираете сервер под Windows, вам надо определиться, компилировать ли LetoDB сервер как службу (режим по умолчанию), или как обычную программу (службы не везде одинаково хорошо запускаются) - тогда вам придется внести поправки в соответствующий makefile, заменив:
- в letodb.hbp: в строках "-cflag=" и "-prgflag=" __WIN_SERVICE__ на __WIN_DAEMON__;- в makefile.bc, makefile.gcc в строке "SRV_MODE =" тоже __WIN_SERVICE__ на __WIN_DAEMON__.
Когда исполняемый модуль сервера LetoDB готов, скопируйте его в выбранный каталог и положите рядом
letodb.ini с нужными вам опциями. Создайте отдельный каталог для баз данных и пропишите его
в letodb.ini
в строке DataPath =
- в противном случае вновь созданные таблицы будут помещаться в каталог с самим
LetoDB. После этого можете считать LetoDB сервер установленным.
Откуда такое название, почему LetoDB?
Потому что я сел писать его "однажды, в студеную зимнюю пору".
Помогите разобраться в режимах работы сервера.
Существуют три режима работы сервера, которые задаются соответствующими установками
в файле конфигурации letodb.ini
:
- Основной режим: Share_Tables и No_Save_WA установлены в 0 или не заданы вообще.
В этом режиме каждый файл открывается серверным модулем в монопольном режиме,
причем только один раз. Когда другой клиент запрашивает открытие уже открытого
сервером файла, новая рабочая область не создается - уже существующая используется
повторно для каждого клиента. Это позволяет сократить общее количество открытых файлов в системе,
сэкономить память под рабочие области и буфера и повысить скорость выполнения ряда операций,
поскольку в монопольном режиме все работает быстрее: не требуются блокировки файлов, используются
буферы. К недостаткам этого режима относятся:
- Невозможность одновременного доступа к таблицам со стороны LetoDB и программ, не использующих LetoDB (хотя далеко не всегда это является недостатком).
- То, что одна рабочая область совместно используется многими клиентами, имеет определенные недостатки. Это постоянный сброс буферов таблиц и индексов, что приводит к снижению производительности в ряде случаев.
- Share_Tables = 1. Этот режим отличается от основного тем, что файлы открываются серверным модулем не в монопольном режиме, а в том, какой запрошен клиентом. Это приводит к некоторому снижению производительности, но зато позволяет работать с таблицами БД и другим программам параллельно с LetoDB.
- No_Save_WA = 1. При этом автоматически устанавливается в 1 и Share_Tables. В этом режиме при каждом запросе клиента на открытие файла создается новая рабочая область. Если 100 клиентов откроют один и тот же файл, он откроется сервером 100 раз, будет создано 100 рабочих областей. С одной стороны, это приводит к большему расходу памяти и к снижению скорости в ряде ситуаций из-за необходимости ставить блокировки, с другой - может привести к повышению производительности в ряде случаев, т.к. решает проблему со вторым недостатком основного режима.
Так все-таки, какой режим выбрать ? Режим с Share_Tables имеет смысл рассматривать только тогда, когда вам реально необходимо использовать таблицы из других программ параллельно с LetoDB - и не забывайте, что режим No_Save_WA включает эту опцию. Что же касается выбора между основным и No_Save_WA - тут мне трудно дать определенный ответ. Это зависит от специфики всего вашего окружения - конфигурации сервера и его ОС, от сети, наконец, от того, в какой манере написаны ваши программы. Надо попробовать оба варианта и выбрать оптимальный. Скажу только, что на сегодняшний момент ( 07.10.2016 ) режим No_Save_WA еще не оттестирован должным образом.
Как работает кэширование записей, как его настраивать?
Когда сервер получает запрос на выполнение операции SKIP, он посылает в ответ не одну запись, а несколько - при этом у клиентской программы формируется буфер с этими несколькими записями. При последующем SKIP'e клиентская программа сначала проверяет наличие нужной записи в этом буфере и только если не находит ее, посылает новый запрос на сервер. Время жизни такого буфера ограничено одной секундой, что вполне достаточно для кэширования серии перемещений по таблице и, вместе с тем, не приводит к тому, что изменения в таблице, сделанные другим клиентом, остались бы незамеченными у вас.
Размер такого буфера по умолчанию - 10 записей, его можно переустановить в letodb.ini
,
за это отвечает параметр Cache_Records. Кроме того, этот параметр можно установить индивидуально
для каждой таблицы вызовом функции leto_SetSkipBuffer( nRecords )
- она
установит размер буфера равным nRecords
для текущей рабочей области.
Кэширование особенно эффективно, когда вы просматриваете подряд много записей, но может несколько замедлять работу, если вы не делаете по нескольку SKIP'ов подряд, так как на отправку нескольких записей требуется, естественно, больше времени, чем на отправку одной. Поэтому для повышения производительности имеет смысл устанавливать размер буфера индивидуально для разных таблиц в зависимости от режима их использования.
Что надо изменить в программе, чтобы начать использовать LetoDB?
Поскольку клиентская часть LetoDB - это RDD, вам надо просто прилинковать библиотеку rddleto к своему приложению и написать пару заклинаний:
REQUEST LETO RDDSETDEFAULT( "LETO" )
Собственно, и все. Ну и, конечно, теперь при создании и открытии таблиц баз данных надо указывать и путь
к серверу - ip или доменное имя и порт (2812, если в letodb.ini
не указан иной). Можно, конечно,
этот путь прописать и в SET PATH
. Смотрите примеры в letodb/tests/
.
Полезно, но не обязательно, установить соединение с сервером перед тем, как начать работать с данными на нем: просто чтобы убедиться, что соединение есть:
IF ( leto_Connect( cPath ) ) == -1 ? "Не удалось подключиться к серверу." Return Nil ELSE ? "Ok" ENDIF
Можно ли в одной программе работать с несколькими LetoDB серверами?
Да, можно. Когда полный путь указан в командах открытия или создания таблицы, в файловых функциях, Leto извлекает из него адрес сервера и номер порта, проверяет, подсоединены ли вы уже к этому серверу и, если нет - подсоединяется к нему. Количество подключаемых серверов не ограничено.
В некоторых функциях, например, в тех, что предназначены для записи/чтения переменных
LetoDB (leto_var...()), путь к серверу не указывается. В этом случае используется
текущее соединение (как текущая открытая рабочая область). В случае, если у вас несколько
открытых соединений, текущее можно установить вызовом функции leto_SetCurrentConnection( cConnString | nConnection )
.
В качестве параметра можно использовать как путь к серверу (это может быть и путь к любому файлу на сервере),
так и порядковый номер соединения. Функция возвращает номер соединения, которое было текущим
до ее вызова:
nConn := leto_SetCurrentConnection( cPath2 ) leto_VarSet( ... ) ... leto_SetCurrentConnection( nConn )
Как правильно оформить транзакцию?
Транзакция начинается всегда с вызова функции leto_BeginTransaction()
и заканчивается вызовом
leto_CommitTransaction()
. Между ними - операции записи в таблицы базы данных: APPEND, REPLACE, DELETE.
Обратите внимание на то, что эти операции записи буферизуются на клиенте и посылаются для исполнения
на сервер вызовом leto_CommitTransaction()
, в то время как остальные операции - перемещения по таблице,
чтения данных выполняются немедленно, как обычно.
Перед исполнением транзакции надо обязательно сделать все необходимые блокировки, иначе она не пройдет.
Если после начала транзакции (вызова leto_BeginTransaction()
) что-то пойдет не так - заблокировать нужную
запись не удастся, например, можно воспользоваться функцией leto_Rollback( lUnlockAll )
для выхода из режима транзакции.
Ниже - небольшой пример, взятый из letodb/tests/test_ta.prg
:
Function ChangeNakl( nSummNew ) Local nDelta leto_BeginTransaction() select NAKL1 if !dbSeek( Dtos(NAKL2->DORD)+STR(NAKL2->NORD) ) .or. !Rlock() leto_Rollback(.F.) Return .F. endif select NAKL2 if Rlock() nDelta := nSummNew - SUMMA replace SUMMA with nSummNew else leto_Rollback() Return .F. endif select NAKL1 replace SUMMA with SUMMA + nDelta leto_CommitTransaction() Return .T.
В каких случаях использовать транзакции?
Транзакции в LetoDB, как и в других клиент-серверных СУБД, предназначены для того, чтобы сделать несколько логически связанных изменений в таблицах базы данных таким образом, чтобы гарантировать сохранение согласованности данных, провести их все - или ни одно из них.
Иными словами, если вам надо сделать несколько взаимосвязанных изменений в данных, где-то добавить запись, где-то заменить, объедините их в транзакцию.
Другое возможное применение - для увеличения скорости. Если вы добавляете, скажем, 10 записей одну за другой, это будет 10 циклов связи с сервером. А если вы объедините эти 10 добавлений в одну транзакцию, то потребуется только один сеанс связи. Но не злоупотребляйте количеством добавлений в одной транзакции: потребуются большие буферы, а это не очень хорошо.
И еще раз хочу подчеркнуть: транзакции работают только на запись информации. Если внутри транзакции у вас есть операции чтения данных или перемещения по таблице, они выполняются сразу, не буферируются, не включаются в транзакцию.
Можно ли использовать LetoDB сервер из программ, написанных на C, Delphi и др. языках?
Можно. В состав клиентской части LetoDB входит статическая библиотека leto.lib (или leto.a, если вы используете Mingw или gcc).
Прилинкуйте ее к своему приложению - и пользуйтесь набором функций для доступа к серверу. Простенькие примеры
программ на C, использующие leto.lib, смотрите в letodb/tests/c_lang/
. Также вы можете
собрать динамическую библиотеку leto.dll - воспользуйтесь для этого Hbmk и letodyn.hbp - и использовать ее со своими приложениями.
Ваше имя:
Адрес электронной почты:
(не предназначено к показу)
  |