А может у SV есть планы организации постраничной блокировки
TPS-таблиц при транзакциях!?
Представь, насколько это было-бы удобно в сетевой работе!
Вряд-ли это возможно. Я слабо представляю себе, как уйти от клинча при такой
блокировке.
WBR,
Nick Tsigouro
В текущей версии TPS-драйвера для блокировки таблицы
операторами LOCK/LOGOUT используется логическая блокировка
средствами САМОЙ ОС через функцию WinAPI LockFile.
Эта функция допускает блокировку ПРОИЗВОЛЬНОГО участка
ЛЮБОГО файла. При чем, в одном файле можно заблокировать
любое кол-во таких участков.
TPS-драйвер блокирует сразу ВСЕ пространство этого файла.
Таким образом, я не вижу большой разницы если вместо
блокировки ВСЕГО файла будет производится блокировка
только ЗАДАННОГО УЧАСТКА этого файла. А именно участка,
занятого обрабатываемыми страницами.
Правда, как ты правильно заметил, такая блокировка
применима не всегда. Не вникая в подробности, можно
сказать, что такая блокировка подойдет только при
поточном добавлении записей и модификации/удалении
одной записи.
Хотя, имхо, коли есть такая возможность, можно было-бы
дать доп.форму операторов LOCK/LOGOUT для блокировки отдельных
записей файла и что-то типа блокировки для добавленных
записей. В последнем случае, сам файл блокировать не надо,
а просто включить стандартный механизм транзакции с
накоплением изменений в памяти и последующей потоковой
выгрузкой в файл при ее завершении.
Я просто файнтазирую, но представь насколько это было-бы
удобно! Разом снялись-бы проблемы с одновременным доступом
к одной записи, обработкой отца и его деток-внуков.
Т.е. в любом случае, алгоритм входа в форму был-бы типа:
Код: Выделить всё
DocsTran &TRANSACTION
Loop
! Начало новой транзакции.
DocsTran &= BEGINTRAN(Docs,Moves)
! Или можно так:
! DocsTran &= NEW(TRANSACTION)
! DocsTran.Init(Docs,Moves)
! Хотя первый вариант мне лично больше нравится
if DocsTran.ErrorCode() then Break.
! Блокируем текущую запись файла документов
! Можно предусмотреть форму этого метода, когда
! можно не указывать последний параметр - в этом случае
! блокировке подлежит запись, считанная последней -
! по аналогии с операторами PUT/DELETE.
DocsTran.LOCK(1,Docs,Pointer(Docs))
if DocsTran.ErrorCode() then Break.
! Блокируем его деток, если есть
Clear(MOV:Record,-1); MOV:Doc_Ndx = DOC:Index
Set(MOV:Doc_Key,MOV:Doc_Key)
Loop
Next(Moves)
! Обработку ошибок чтения опускаю
if ErrorCode() OR (MOV:Doc_Ndx <> DOC:Index) then Break.
DocsTran.LOCK(1,Moves,Pointer(Moves))
if DocsTran.ErrorCode() then Break.
.
if DocsTran.ErrorCode() then Break.
.
if DocsTran.ErrorCode()
Message('Невозможно начать редактирование документа!')
do ProcedureReturn
.
Если успешно заблокировали ВЕСЬ документ, то дальше СПОКОЙНО
работаем как с формой самого документа, так и с его записями -
существующие записи уже никто НЕ ТРОНЕТ, а добавляемые дочерние
записи просто еще не появятся в самой таблице - работает
механизм транзакции с накоплением изменений в памяти!
При выходе из формы:
Код: Выделить всё
ProcedureReturn Routine
...
if (LocalResponse = RequestCancelled) OR DocsTran.ErrorCode()
DocsTran.RollBack()
else
DocsTran.Commit()
.
Dispose(DocsTran)
И все!!!
Не нужны никакие временные очереди с ручным заполнением,
последующей синхронизацией и удалением добавленных деток
в случае отката!
Кстати!
Сейчас вот подумал, а как решаются подобные вопросы
на SQL-серверах со страничной/построчной/поколоночной
блокировками?
К примеру, если я в рамках транзакции "напоролся" на
запись, заблокированную другой транзакцией - что будет?
"Обломится" транзакция или сработают какие другие механизмы?
=============================
С уважением,
Олег А. Руденко
(Добавление)
Таким образом, я не вижу большой разницы если вместо
блокировки ВСЕГО файла будет производится блокировка
только ЗАДАННОГО УЧАСТКА этого файла. А именно участка,
занятого обрабатываемыми страницами.
Вот именно в этом случае и возникает опасность клинча. Ты заблокировал
какие-то блоки, я заблокировал другие. Теперь тебе нужно то, что я уже
захватил. Ты ждешь, пока я освобожу. Если мне не понядобятся твои блоки, я
благополучно завершу свою транхакцию, и ты продолжишь работу, а если мне
понадобятся твои, то будем висеть и в лучшем случае ждать таймаута.
WBR,
Nick Tsigouro
Вот именно в этом случае и возникает опасность клинча. Ты заблокировал
какие-то блоки, я заблокировал другие. Теперь тебе нужно то, что я уже
захватил.
...и в этом случае сервер возвращает что-то типа EDEADLOCK...
--
Best regards,
Maxim Yemelyanov,
Enigma Soft Company
phone:
+380 572 177977
WEB:
http://enigmasoft.com.ua
e-mail:
clalist@enigmasoft.com.ua
ICQ:
12253836
(Добавление)
BTRIVE 6.15 имеет страничную блокировку записей.
PERVASIVE 2000 по моему уже имеет блокировку по записям.
С уважением,
Ставич Олег
Укрсиббанк г.Харьков
oldstav@ukrsibbank.com
Вот именно в этом случае и возникает опасность клинча. Ты заблокировал
какие-то блоки, я заблокировал другие. Теперь тебе нужно то, что я уже
захватил. Ты ждешь, пока я освобожу. Если мне не понядобятся твои блоки, я
благополучно завершу свою транхакцию, и ты продолжишь работу, а если мне
понадобятся твои, то будем висеть и в лучшем случае ждать таймаута.
Хм... В приведенном тобою случае я не вижу совершенно
никакой разницы в сравнении с текущим положением -
сейчас аналогично - я блокирую один файл, ты блокируешь
другой. Если мне понадобится твой файл, то я так-же
"отвалюсь" по таймауту с ошибкой!
Я же в предыдущем письме привел вариант (и не надуманный -
а реальный!), когда такая выборочная блокировка была-бы
очень полезна.
А при поточной модификации/удалении записей файла самым
лучшим, естественно, будет именно полная блокировка
этого файла.
=============================
С уважением,
Олег А. Руденко
Написал: ClaList(2)