MylnikovDm » 26.04.2018 14:54:39
Уважаемый bpg, у вас в принципе не правильная логика работы с сетевой SQL базой данных.
Транзакция должна открываться в тот момент, когда вы хотите получить некий набор данных, после чего закрываться.
При внесении изменений в базу данных, точно такая же логика. Когда все данные в форме заполнены, оператор нажимает Ok, запускается транзакция на внесение изменений, всё, что необходимо, вносится в базу данных, после чего транзакция сразу же закрывается. А для просмотра тех данных, которые оператор только что внёс, они снова загружаются с сервера, но уже через другую транзакцию.
То есть, если у вас оператор собирается печатать договор, то вы должны данные для этого договора поднять с сервера через НОВУЮ транзакцию, которая запускается в момент, когда оператор нажал кнопку "сформировать договор".
При просмотре всяческих списков и выборок из базы данных, это можно сделать через транзакцию в режиме READ COMMITTED, которая будет видеть все подтверждённые данные. Но тут нужно понимать, что данные становятся подтверждёнными именно в тот момент, когда завершается через commit та транзакция, через которую данные вносятся на сервер. То есть, если у вас девочка-оператор внесла данные в базу, но её транзакция в программе не была committed, то вы всё равно не сможете увидеть эти данные. Другими словами, если у вас в программе неправильно выстроена логика работы с транзакциями, то механизм сообщений (event'ов) вас всё равно не спасёт.
Ещё один момент, который необходимо учитывать при работе с сервером FireBird. Про последние компоненты, которые сейчас есть в Lazarus, ничего конкретного сказать не могу, так как с FireBird'ом их не тестировал, но в тех компонентах, которые были раньше, механизм с использованием TConnection и TTransaction работал с ошибками, когда попытка открыть вторую транзакцию через одно и тоже соединение приводило к откату и закрытию первой транзакции в этом соединении. Из-за этого нам в программе пришлось сделать два отдельных TConnection. Одно подключение работало только на чтение и режим транзакции у него был выставлен Read Committed, READ_ONLY, NOWAIT, а второе использовалось для внесения изменений в базу данных. При этом второе подключение устанавливалось с базой непосредственно перед выполнением запросов на внесение изменений, а после выполнения этих запросов сразу же закрывалось. Ему, кстати, тоже можно выставить Read Commited и NOWAIT, но уже с режимом READ_WRITE.
Итого. Все данные с сервера смотрим через одну транзакцию с режимом изоляции Read Committed, а все изменения в базу данных вносим через другое подключение, у которого транзакция запускается непосредственно перед внесением изменений и сразу же закрывается. Тогда вы на всех машинах будете видеть в первых соединениях все внесённые изменения. Но видеть вы их будете, само собой, в результатах тех запросов, которые будут выполнены к серверу уже после того, как была завершена транзакция на внесение изменения в базу данных. То есть, если ваш запрос был выполнен раньше и потом вы только просматриваете его результаты в таблице, то данные необходимо будет обновить. Это делается либо вручную оператором путём нажатия кнопки "refresh", которая должна повторно запустить запросы на выборку данных, либо через систему обработки сообщений, которая ту же самую повторную выборку данных с сервера запускает в автоматическом режиме.
Но, ещё раз повторюсь, что если ваши транзакции, которые вносят изменения в базу данных, тут же не закрываются, то изменений вы не увидите.
P.S. Раньше в компонентах работы с базами данных на SQL серверах была ошибка, из-за которой реально транзакция закрывалась не когда вы вызывали у неё Commit или Rollback, а в момент закрытия соединения. То есть, при вызове TTransaction.Commit ничего не происходило, а реально завершалась транзакция при вызове TConnection.Close. Пофиксили ли это сейчас или нет, не знаю, поскольку сам уже давно с FireBird из Lazarus не работал.