Другие языки программирования и технологии

Настройка параметров транзакции в Firebird

Есть офисное приложение, работает несколько офисов, от 5 до 25 клиентов в сети. Все как бы отлично, и т. к. данные обновляются кратковременно, никаких deadlock не возникает никогда. Пишущие транзакции имеют вид write nowait rec_version read_committed.
Сейчас решил прикрутить обновление exe-файла из самой БД. Замысел такой: один из клиентов в офисе обновляется, его exe автоматом впихивается в общую БД программы, все запущенные клиенты получают от сервера команду обновиться, ползатель видит сообщение, что необходимо перезапуститься, закрывает/открывает клиента. При запуске проверяется наличие более новой версии exe в БД, и если она там есть, то клиент его высасывает из БД во временный файл, сам запускает другой exe рядом и завершается, а тот переименовывает временный файл в exe и стартует его.
А теперь вопрос. Как правильно прописать параметры транзакции, которая будет записывать exe в БД и какие у той, что будет читать сведения о версии? Размер exe на данный момент порядка 38 мб, функционал постоянно растет, т. е. выполняться будет несколько секунд точно. Т. е. я бы хотел каким-то образом сделать так, чтобы при обновлении одним клиентом содержимого БД, если вдруг второй в этот момент пытается запуститься, то читающий клиент приостановил свое чтение, пока таблица, содержащая blob с ехе файлом не освободится (уже с новым файлом внутри) . Или, другими словами, как блокировать таблицу, чтобы другие клиенты ждали, пока она освободится?
Спасибо! PS Delphi+FIBPlus+Firebird 2.5, если это важно
Вы хотите того, чего хотеть не должны. Блокировки не просто не нужны, а даже вредны.

Вы хотите подвесить клиента в тот момент, когда большие данные грузятся на сервер.
Это не есть хорошо по нескольким причинам:
-- имеется шанс того, что данные загрузятся не успешно или пишущая транзакция не завершится
-- любое вмешательство в таблицу не со стороны вашей программы записи (например из IBExpert или программы-злоумышленника) может вызвать блокировку
Как результат: ни одна из программ-клиентов не запустится, то есть работа офиса будет остановлена.

Маловероятно, что вы будете одновременно заносить обновление, но всё же.
На запись:
read write
wait
rec_version
read_committed
На получение:
read
nowait
rec_version
read_committed
Работайте честно, не пытаясь блокировать. А уведомление о готовности новой версии высылайте после успешного завершения транзакции записи.

ЗЫ
Была примерно такая задача, обновляющая набор небольших текстовых конфигурационных файлов.
была таблица
(
id on generator, - просто идентификатор
config_id, - идентификатор того, что заменяем
next_id, - если эта не актуальна ссылка на следующую актуальную
blob - сами данные
)

Порядок работы на модификацию:
Вставка записи с config_id = null и загрузка blob. Чтение blob, проверка контрольных сумм.
В случае успеха замена next_id на id этой в предыдущей версии, и установка config_id. Commit.
Неудача - rollback.

При запуске клиентской программы в режиме быстрого старта выбирались ID старше, чем запомненный при последнем обновлении и имеющие next_id = null. В режиме полного обновления вытаскивались все записи с next_id = null. Разумеется с ненулевыми config_id.
После успешного обновления запомнить новый старший ID.
Андрей Михайлов
Андрей Михайлов
11 112
Лучший ответ
Сергей Любин Спасибо! Поставим wait на запись, посмотрим как будет происходить.
а разместить exe файл на ftp в vdfs или другом подобном месте, шаре. ? ТОгда клиенты будут тянуть одновременно .
ФВ
Фото Видео
15 367