Автор | Сообщение |
alkresin
|
| moderator
|
Пост N: 31
Зарегистрирован: 06.07.06
|
|
Отправлено: 31.01.08 11:36. Заголовок: Leto DB Server (продолжение)
Только что открыл на 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 на Харборе, ... и вообще все в наших руках :). Кто хочет участвовать в разработке, тестировании - пишите.
|
|
|
Ответов - 193
, стр:
1
2
3
4
5
6
7
8
9
10
All
[только новые]
|
|
PSP
|
| постоянный участник
|
Пост N: 272
Зарегистрирован: 27.01.07
|
|
Отправлено: 26.01.10 17:44. Заголовок: Pasha пишет: Транза..
Pasha пишет: цитата: | Транзакции делал Александр. Попробуйте написать ему напрямую |
| Спасибо.
|
|
|
alkresin
|
| moderator
|
Пост N: 257
Зарегистрирован: 06.07.06
|
|
Отправлено: 29.01.10 10:01. Заголовок: Речь о блокировках п..
цитата: | Речь о блокировках при работе с транзакциями. |
| Повторю здесь то, что писал Сергею по email. цитата: | Если при активной транзакции снять блокировку(ки), то она(и) успешно снимаются, не дожидаясь выполнения Leto_CommitTransaction(). |
| При попытке разблокировке записи во время транзакции должна выскочить ошибка "LETO/1031 Syntax Error". цитата: | По идее-то все действия, производимые с базой после Leto_BeginTransaction(), должны делаться в Leto_CommitTransaction() или я не прав? |
| Не все, а только добавление, удаление, модификация записи. Некоторые операции вообще запрещены во время транзакции, в том числе и снятие блокировки. Кстати, если вызвать Leto_CommitTransaction( .t. ) вот так, с параметром .t., все записи будут по ее окончании разблокированы автоматически. ... Я взял за основу рекомендации из руководства к ADS: File locks and/or record locks must be acquired on data before it can be updated. Once data locks are acquired, they are maintained throughout the entire transaction to ensure that the updates can be made to the database during the commit of the transaction. Record and file locking is best performed before a transaction begins. If an update needs to be made to a record in order to complete the transaction, and the lock operation on that record is attempted during the transaction and is unsuccessful, the corresponding update cannot be performed. The application will most likely need to roll back the transaction. All previous update and insert operations performed prior to the failed data lock will be rolled back due to poor transaction programming. If all explicit data locks are acquired before a transaction begins, unnecessary rollbacks will be prevented. Explicit data locking during a transaction is not recommended, but is supported. Some data locking behavioral differences exist when data locks are performed during a transaction. Review the "Advantage TPS Special Conditions" section if data locking must be done during a transaction. Хотя здесь не запрещается категорически блокировать записи во время транзакции и ничего не говорится про деблокирование, но логика ясна и, мне кажется, разумна: 1. Подготовка транзакции: блокировки, сбор данных для последующей записи; 2. Осуществление транзакции; 3. Деблокировка. Такая последовательность обеспечивает успешное проведение транзакции, практически гарантирует, что она будет вся осуществлена. .... А как вам вот такой вариант ( я давно подумывал о нем, но все руки не доходят, да и практической необходимости не было ): Добавить в Leto_BeginTransaction() параметр, котрый определяет эту транзакцию, как "автоблокировочную" - т.е. все необходимые блокировки делаются сервером при выполнении Leto_CommitTransaction(). Это повышает риск неудачного завершения транзакции, теперь надо обязательно проверять код возврата Leto_CommitTransaction() и повторять ее в случае неудачи, но упрощает подготовку к транзакции и заметно ускоряет ее.
|
|
|
alkresin
|
| moderator
|
Пост N: 258
Зарегистрирован: 06.07.06
|
|
Отправлено: 29.01.10 10:15. Заголовок: Pasha пишет: ... 16..
Pasha пишет: цитата: | ... 16-й и 17-й элемент массива будут соответственно дата (Long) и время: целая часть - секунды, дробная часть - миллисекунды после полуночи Если Александр не против, можно это сбросить на CVS |
| Мне кажется, что лучше это сделать отдельной функцией, что-то вроде: HB_FUNC( LETO_MGGETTIME ) { if( pCurrentConn ) { if( leto_DataSendRecv( pCurrentConn, "mgmt;03;\r\n", 0 ) ) { PHB_ITEM temp; PHB_ITEM aInfo; char szData[32]; char * ptr = leto_firstchar(); int i; if( *(ptr-1) == '+' ) { aInfo = hb_itemArrayNew( 2 ); for( i=1; i<=2; i++ ) { if( !leto_getCmdItem( &ptr, szData ) ) { hb_itemReturn( aInfo ); hb_itemRelease( aInfo ); return; } ptr ++; temp = hb_itemPutCL( NULL, szData, strlen(szData) ); hb_itemArrayPut( aInfo, i, temp ); hb_itemRelease( temp ); } hb_itemReturn( aInfo ); hb_itemRelease( aInfo ); } } } } ну и соответственно в letofunc: case '3': { ... Если вы не возражаете, сбросьте на CVS, пожалуйста.
|
|
|
Pasha
|
| Администратор
|
Пост N: 1318
Зарегистрирован: 23.05.05
|
|
Отправлено: 29.01.10 10:29. Заголовок: Хорошо, сброшу..
Хорошо, сброшу
|
|
|
PSP
|
| постоянный участник
|
Пост N: 275
Зарегистрирован: 27.01.07
|
|
Отправлено: 29.01.10 21:01. Заголовок: alkresin пишет: Я в..
alkresin пишет: цитата: | Я взял за основу рекомендации из руководства к ADS: |
| O'kay, я согласен с этим. Спасибо. :)
|
|
|
PSP
|
| постоянный участник
|
Пост N: 276
Зарегистрирован: 27.01.07
|
|
Отправлено: 29.01.10 21:02. Заголовок: alkresin пишет: А к..
alkresin пишет: цитата: | А как вам вот такой вариант ( я давно подумывал о нем, но все руки не доходят, да и практической необходимости не было ): Добавить в Leto_BeginTransaction() параметр, котрый определяет эту транзакцию, как "автоблокировочную" - т.е. все необходимые блокировки делаются сервером при выполнении Leto_CommitTransaction(). Это повышает риск неудачного завершения транзакции, теперь надо обязательно проверять код возврата Leto_CommitTransaction() и повторять ее в случае неудачи, но упрощает подготовку к транзакции и заметно ускоряет ее. |
| Ваша идея мне нравится. Единственное, "авторазблокировка" не должна касаться записей, заблокированных до начала транзакции. А повтор транзакции в cлучае неудачи - не проблема, имхо. Проще один раз проверить код возврата Leto_CommitTransaction(), чем проверять при подготовке к транзакции каждый RLock(). Это - мое мнение.
|
|
|
Andrey
|
| постоянный участник
|
Пост N: 1067
Зарегистрирован: 12.09.06
|
|
Отправлено: 30.01.10 15:29. Заголовок: Обращаюсь к PSP ! Та..
Обращаюсь к PSP ! Так как вы разбираетесь с транзакциями, очень прошу (я думаю и другие поддержат) сделать небольшой пример с пояснениями, как нужно правильно делать эти операции... Потратьте чуть-чуть времени для всех нас ...
|
|
|
Dima
|
| |
Пост N: 1359
Зарегистрирован: 17.05.05
|
|
Отправлено: 30.01.10 16:06. Заголовок: Andrey Из NG по ADS..
Andrey Из NG по ADS Смысл транзакций в Leto DB Server , вероятно тот же , или я вопроса не понял ? :) Скрытый текст BEGIN TRANSACTION Определяет начало транзакции ------------------------------------------------------------------------------ Синтаксис BEGIN TRANSACTION Описание Эта команда отмечает начало Advantage TPS-транзакции. Из той точки Вашего приложения, где расположена команда BEGIN TRANSACTION, каждая встреченная команда APPEND или REPLACE, вставленная перед соответс- твующей командой COMMIT TRANSACTION или ROLLBACK TRANSACTION, будет считаться одной транзакцией. Учтите: Текущая рабочая область должна использоваться Advantage RDD для того, чтобы работали Advantage TPS-команды или функции. Если Вы вводите Advantage TPS-команду или функцию не в рабочей области, ис- пользуемой Advantage RDD, Вы получите ошибку 6034 - "Для транзакций требуется рабочая область Advantage" ("Advantage workarea required for transaction"). Как только выполнится команда BEGIN TRANSACTION, любые изменения (REPLACE и APPEND), произведенные с базой данных, будут помещены в журнал транзакций. Другие пользователи, использующие ту же базу дан- ных, не увидят этих изменений до тех пор, пока не завершится транзак- ция. Когда это произойдет, изменения запишутся в базу данных и индек- сы. Например, если Вы в примере, описанном ниже, остановили отладчик на операторе COMMIT TRANSACTION, другие пользователи этих двух баз дан- ных не смогут увидеть результатов команд APPEND и REPLACE пока Вы не пройдете COMMIT TRANSACTION. Для них запись будет содержать первона- чальные значения. Добавление записей не будет видно остальным. В пределах транзакции могут быть произведены изменения только над те- ми таблицами, которые расположены на том же файл-сервере. Пример В этом примере производится блокировка необходимой записи в первой таблице - CUSTOMER.DBF. Если блокировка происходит успешно, начинает- ся транзакция, в пределах которой производятся изменения в двух таб- лицах. После выполнения команд REPLACE, команда COMMIT TRANSACTION физически передает изменения сетевой ОС, которая производит физичес- кую запись данных на жесткий диск. Как упоминалось ранее, код между командами BEGIN TRANSACTION и COMMIT TRANSACTION должен содержать только команды REPLACE и APPEND. В этом случае транзакция точно описана и будет выполнена. Если между коман- дами BEGIN TRANSACTION и COMMIT TRANSACTION присутствует небольшое количество другого кода, то увеличивается вероятность того, что тран- закция завершится с ошибкой и потребуется откат транзакции. // Обеспечим блокировку первой базы данных и добавим необходимые записи SELECT CUSTOMER IF !RLock() Alert( "Невозможно заблокировать запись в CUSTOMER для транзакции" ) RETURN( .F. ) ENDIF // Начало транзакции BEGIN TRANSACTION // Модификация полей в текущей записи из CUSTOMER.DBF SELECT CUSTOMER REPLACE c_lname WITH cLastName REPLACE c_fname WITH cFirstName REPLACE c_add1 WITH cAdd1 REPLACE c_city WITH cCity REPLACE c_state WITH cState REPLACE c_zip WITH cZip // Добавление 2 записей в ORDER.DBF и редактирование // соответствующей информации APPEND BLANK REPLACE o_ordernum WITH cOrderNum REPLACE o_orddate WITH dOrdDate REPLACE o_sales WITH cSalesRep REPLACE o_terms WITH cTerms REPLACE o_amount WITH nAmount REPLACE o_salestax WITH nSalesTac APPEND BLANK REPLACE ol_ordernum WITH cOrderNum REPLACE ol_itemnum WITH cItemNum REPLACE ol_descr WITH cItemDescr REPLACE ol_cost WITH nCost REPLACE ol_numof WITH nNumItems REPLACE ol_subtotal WITH nSubTotal // Завершение транзакции COMMIT TRANSACTION
|
|
|
|
PSP
|
| постоянный участник
|
Пост N: 277
Зарегистрирован: 27.01.07
|
|
Отправлено: 30.01.10 17:25. Заголовок: В общем-то Dima уже ..
В общем-то Dima уже ответил. Добавлю, что для меня возможность использовать транзакции была решающим фактором для использования сервера LetoDB. Транзакция либо выполняется полностью, либо не выполняется вообще. Т.е., если в момент выполнения транзакции (между BeginTransaction и CommitTransaction) с рабочей станцией что-то случилось (вырубилось питание, случилась run-time error и т.п.), сервер не запишет в таблицы ошибочные или неполные данные. Соответственно, таблицы и индексы не повредятся. Это очень удобно в плане целостности данных. Как-то так...
|
|
|
PSP
|
| постоянный участник
|
Пост N: 279
Зарегистрирован: 27.01.07
|
|
Отправлено: 30.01.10 19:19. Заголовок: Pasha пишет: Хорошо..
Pasha пишет: Еще не сбрасывал?
|
|
|
Pasha
|
| Администратор
|
Пост N: 1323
Зарегистрирован: 23.05.05
|
|
Отправлено: 30.01.10 22:34. Заголовок: PSP пишет: Еще не с..
PSP пишет: Только что сбросил: 2009-01-30 21:40 UTC+0200 Pavel Tsarenko (tpe2/at/mail.ru) * source/client/letomgmn.c * source/server/letofunc.c * Readme.txt + added LETO_MGGETTIME function. It's return array with server date and time (seconds after midnight): {dDate, nSeconds} Не стал возвращать одну переменную типа DateTime, в харборе функция DateTime() не возвращает миллисеунды, а они, как я понимаю, нужны.
|
|
|
|
PSP
|
| постоянный участник
|
Пост N: 280
Зарегистрирован: 27.01.07
|
|
Отправлено: 31.01.10 09:52. Заголовок: Pasha пишет: Не ста..
Pasha пишет: цитата: | Не стал возвращать одну переменную типа DateTime, в харборе функция DateTime() не возвращает миллисеунды, а они, как я понимаю, нужны. |
| Конечно нужны. Все правильно. Спасибо большое!
|
|
|
Pasha
|
| Администратор
|
Пост N: 1325
Зарегистрирован: 23.05.05
|
|
Отправлено: 31.01.10 16:43. Заголовок: К слову. Непонятно, ..
К слову. Непонятно, почему в харборе(ах) в функции DateTime() обрезаны миллисекунды. Разрядность double позволяел хранить и юлианские дни в целой части, и секунды с миллисекундами в дробной. Вот аналог DateTime() с миллисекундами: #include "hbapi.h" #include "hbdate.h" HB_FUNC( DATETIME2 ) { int iYear, iMonth, iDay, iHour, iMinute; double dSeconds; hb_dateToday( &iYear, &iMonth, &iDay ); dSeconds = hb_dateSeconds( ); iHour = (int) (dSeconds / 3600); iMinute = (int) (dSeconds / 60) - iHour*60; dSeconds -= iHour*3600 + iMinute * 60; hb_retdt( iYear, iMonth, iDay, iHour, iMinute, dSeconds, 0 ); }
|
|
|
Ответов - 193
, стр:
1
2
3
4
5
6
7
8
9
10
All
[только новые]
|
|