FoxPro Club Главная

Конференция Решения Фотоальбом Сайт М.Дроздова Статьи Файловый архив Книга Visual FoxPro 9.0 Русский Help для Visual FoxPro
Пользователей: 9176
Вход
Как можно подружить VFP5/6 с TTS NetWare.Или индексы больше не падают.

Наверняка любой программист, пишущий на Visual FoxPro, многопользовательские приложения сталкивался с проблемами падения индексов или порчи DBF файлов на файл сервере ...


 
Прислал: Зайцев Юрий Владимирович   Категория: Работа с данными


Как можно подружить VFP5/6 с TTS NetWare.Или индексы больше не падают.

Наверняка любой программист, пишущий на Visual FoxPro, многопользовательские приложения сталкивался с проблемами падения индексов или порчи DBF файлов на файл сервере.

Используя библиотеку GPLIB MHSOFTWARE http://www.mhsoftware.com/gplib.htm Можно избежать этих проблем если не теоретически то практически навсегда. Для начала, правда, необходимо установить 32 битового клиента от NOVELL.
Еще необходимо получить http://www.mhsoftware.com/bin/gp30.exe библиотеку.
Она имеет статус TRIAL.
У меня установка практически прошла без проблем. Использую я VFP6 + SP4 Window 2000 pro Русский и 32 битовый Novell Client .
После установки выяснилось, в GPLIB нет места для VFP6, возможно в MHSOFTWARE не знали о выходе VFP6 и не добавили в пример обработку Visual FoxPro 6.

Легким движением исправляем эту нелепость в демонстрационном коде:

Смотрите самое начало модуля GPSTART.PRG

DO case
CASE version()="Visual FoxPro 03"
nFoxVer=3
CASE version()="Visual FoxPro 05"
nFoxVer=5

**** Я добавил только эти две строчки
CASE version()="Visual FoxPro 06"
nFoxVer=5
**** Конец модификации

OTHERWISE
do form ShowMsg with "FOX_VER"
return .f.
ENDCASE

Демонстрационный код работает что дальше.

Для защиты своих данных, я использую несколько функций GPLIB.

N_TTSAvail() - Сообщает доступна ли TTS
N_TTSBegin() - Начало транзакции
N_TTSCommt() - Завершение транзакции
N_TTSRollB() - Откат транзакции
N_SetAttr( mFile, ”+T” ) - Установить флаг TTS на файл
N_SetAttr( mFile, ”-T” ) - Снять флаг TTS c файла
N_FileInfo(mFile) - Получить информацию о файле на файлсервере NetWare

Этого списка функций достаточно, что бы забыть проблемы с падением индексов или таблиц.

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

На файлы необходимо установить флаг TTS.

Представим себе нам необходимо вести базу операций и менять сальдо по счетам.
У нас есть база операций TEST и база остатков на счетах SALDOTST.
При каждой логической операции нам необходимо добавлять запить в TEST и менять остаток на счете в базе SALDOTST. В реальной жизни одна транзакция может менять гораздо больше количество файлов и добавлять записи в несколько таблиц.
Нам необходима целостность данных как логическая так и физическая.
Логическая целостность подразумевает списание со счета 1 зачисление на счет 2 и добавление в таблицу TEST записи
Физическая целостность, это когда таблицы или CDX не портятся при прерывании записи в них при потере питания или сетевого соединения.

SEEK СЧЕТ-1
Replace OSTATOK with OSTATOK - OUMMAOP

SEEK СЧЕТ 2
Replace OSTATOK with OSTATOK + OUMMAOP

INSERT INTO TEST from memvar


У нас получилось 3 шага, если представить что между шагом 1 и 2 произошел сбой,
что маловероятно, но возможно. Мы получим не корректную информацию.
Со счета-1 деньги исчезли, но не появились на счете-2 и не попали в базу операций TEST.

Теперь приведем пример как это избежать, применяя GPLIB.

Function trtest
Parameter mTranTyp
Private nTransNo,mCod

&& 0 - одинокая проводка завершаем трнзакцию в модуле
&& 1 - транзакция не завершена
&& выходим
&& - без разблокировки захваченых записей
&& - без завершения транзакции
&& удобно применять при массовых транзакциях
&& следует только убедиться в достаточной длине транзакционного буфера
&& не рекомендую работать в данном режиме при большом количестве вызовов с параметром 1
&&
&& 2 - завершаем транзакцию
&& происходит только разблокировка и завершение транзакции
&&

mCod = 0
If mTranTyp <> 2
If mTYPBL = 1
* 1-й вариант
If mTranTyp = 0
mLock = flock(mFile) && Блокируем ФАЙЛ на момент транзакции
Endif
Else
* 2-й вариант блокируем только записи с которыми работаем на момент транзакции
&& В моем случае корректность при поиске гарантируется
&& Работает значительно быстрее чем 1-й вариант
Seek m.LSD
If found()
If abs(ISS) >= m.SUMMAOP
mRECD = alltrim(str(recno()))
Else
mCod = 1 && Нехватка средств
Endif
Else
Wait window "Не найден "+m.LSD
Endif
If mCod = 0
Seek m.LSK
If found()
mRECK = alltrim(str(recno()))
Else
Wait window "Не найден "+m.LSK
Endif
mLOCKRECDK = mRECD+","+mRECK
If mTranTyp = 0
mLock = rlock( mLOCKRECDK , 'SALDOTST' )
Endif
Endif
Endif

If mCod = 0

If N_TTSAvail() &&

If mTranTyp = 0
nResult =N_TTSBegin() && Начало транзакции
Endif

Select SALDOTST
Seek m.LSD
If found()
Replace obd with obd + m.SUMMAOP
If TYPLS = 1 && С активного
Replace ISS with ISS - m.SUMMAOP
Else && С пассивного
Replace ISS with ISS - (m.SUMMAOP - m.SUMMAOP - m.SUMMAOP)
Endif
Replace userop with m.userop
Endif

Seek m.LSK
If found()
Replace obk with obk + m.SUMMAOP
If TYPLS = 1 && На активный
Replace ISS with ISS + m.SUMMAOP
Else && На пассивный
Replace ISS with ISS + (m.SUMMAOP - m.SUMMAOP - m.SUMMAOP)
Endif
Replace userop with m.userop
Endif
&& Операцию в базу операций
Insert into TEST from memvar
If mTranTyp = 0
nResult=N_TTSCommt() && Конец транзакции
Endif
Else
Wait window 'TTS was not available!'
Endif
If mTranTyp = 0
Unlock all
Endif
Endif
Else
nResult=N_TTSCommt() && Get the transaction number
Unlock all
Endif

Return mCod



В примере четко видно, необходимо блокировать записи, которые мы меняем, до того как мы используем TTS.

Если в какой либо момент после объявления транзакции N_TTSBegin()
Происходит сбой, зависание сервера, зависание клиента или разрыв сети потеря питания
При запуске сервера, при соответствующей настройке NetWare, все незавершенные транзакции откатятся. И таблицы с индексами примут те значения, которые были в них до начала транзакции, на которой произошел сбой.
Что собственно и требовалось.


Для работы TTS необходимо установить флаг TTS на те файлы которые вы
хотите обрабатывать под эгидой TTS.
При этом это не только DBF таблицы но и CDX и FPT и вообще любые файлы, вы же можете использовать транзакционный механизм даже при операциях на низком уровне FOPEN FWRITE FCLOSE. Все же NetWare TTS замечательная штука! К сожалению, в любимой мной операционной системе NT и ее всех клонах нет такой замечательной функции.

Немого хотелось сказать о командах VFP

BEGIN TRANSACTION
END TRANSACTION
ROLLBACK

Эти команды сильно облегчают страдания с падением таблиц и индексов
Но TTS NetWare надежней, чем эти встроенные команды.
Разумеется, если таблицы расположены на сервере NetWare.
С локальными таблицами, проблемы решать придется с менее надежными командами управления транзакциями VISUALFOXPRO.

Короткая работающая программа. GTEST в архиве GTEST.ZIP
К данной статье прилагается.

После компиляции и запуска нажмите кнопку СОЗДАТЬ ТЕСТОВУЮ БАЗУ

Проверьте баланс

Запустите ТЕСТ, желательно с нескольких станций.

Во время работы теста попробуйте выключить питание на клиентской машине, или просто выдернуть из сетевой карты кабель, у меня еще была возможность выключать питание на сервере!

Если TTS на NetWare правильно настроен, то при перезагрузке сервера откат транзакций произойдет автоматически. Иначе вашему администратору придется на каждой зависшей транзакции отвечать на утомительные вопросы и что самое страшное, при неверном ответе можно записать в данные те значения
которые они имели бы без применения TTS. Поэтому лучше установить флаг

Auto TTS Backout Flag = ON

В файле STARTUP.NCF.

Auto TTS Backout Flag: OFF (задается лишь в STARTUP.NCF)
Описание: авто-отмена TTS при перезагрузке (пропуск подсказок)

В AUTOEXEC.NCF на NetWare посмотреть следующие настройки и при необходимости можно их ввести.

set tts abort dump flag = on

Maximum Transactions = 10000

TTS Abort Dump Flag: ON
Описание: включает вывод данных отказанных транзакций
в файл регистрации

Maximum Transactions: 10000
Границы: 100 -- 10000
Описание: максимальное число конкурентных транзакций в системе

 
Сделайте оценку этого решения Плохо Удовлетворительно Так себе Хорошо Отлично Текущая оценка: (4.927) Вложение [59.65]kb
Дополнения пользователей
Как можно подружить VFP5/6 с TTS NetWare.Или индексы больше не падают.
[+][?]
akudenzov@radon.ru
21.06.01 06:31:33

Использую GPLib в своих приложениях
более 4-лет, Но индекс иногда возьмет и упадет
akudenzov@radon.ru
21.06.01 06:34:49

Как бы это привязать к буферизации таблиц, чтобы TABLEUPDATE() вызывал TTS
Кирилл Макаров
02.09.02 08:00:09

На работе используем самостийно написанную библиотечку функций. Использовали функции
NWTTSBeginTransaction,NWTTSEndTransaction,NWTTSAbortTransaction (и еще кучу других) из
CALWIN32.DLL. Работает массово с ноября прошлого года + пол-года прока программу писали. Индекс ни
разу не упал. С буферизацией тоже работает хорошо. Необходим Novell Client 32. И еще замечена не
совсем корректная работа нескольких программ на одной машине, использующих TTS под WinNT 4.0. Под
98 все хорошо.
[Дополнить]



© 2000-2017 Fox Club 
При размещении любых материалов с сайта на других ресурсах- прямая ссылка на www.foxclub.ru обязательна
Яндекс.Метрика