lazarus = Firebird - транзакции

Вопросы программирования и использования среды Lazarus.

Модератор: Модераторы

Re: lazarus = Firebird - транзакции

Сообщение bpg » 17.04.2018 20:41:09

Ого, сколько написали ;-)
Короче, попытаюсь подробнее.... есть приёмная комиссия, в разных корпусах сидят девочки (студентки), к ним заходят люди и они только вносят в базу данные. Естественно они имеют право ошибаться.
В другом месте другой человек берет из базы данные, печатает договор и т.д. и и приглашает родителей или абитуриента подписать. И вот тут и засада. Все думают что в базе данные нормальные, а на самом деле.... я допустим увидел, что Иванов Иван Иванович женщина и допустим эскимос, делаю правку и никто эти данные не видит, они не обновились, а этот человек спокойно печатает договор с усатой женщиной. Поэтому и нужны мне ивенты и обязательная синхронизация данных, если честно, всегда думал. что этим занимается сам сервер баз данных. То же самое происходит при формировании отчета, ты допустим решил глянуть сколько по каким специальностям документов подано, а тут оказывается данные еще не обновились.
А тут выплывает такой косяк, на тестовых машинах пробовал одновременно и в программе что-то делать, и тут же в IBExpert правлю таблицу, все работает. Обновляется и т.д. Но до тех пор, пока я делаю одно изменения и сразу комит транзакции, а если же я удалил несколько записей или сделал правки, а только потом делаю комит, то прога намертво виснет.

Что посоветуете, может я себе чересчур мозг выи...ал? Может все проще делается?
Проект бесплатный и на чистом энтузиазме.

P.S. В голове у меня крутиться что-то такое. Если пользователь имеющий полномочия печатать справки, отчеты , договора и т.д. начал что то этакое делать, то всем программа должна послать какое то сообщение, что все теперь только readonly. И после формирование снова сообщение, продолжайте работать. Это как реализовать? Или все проще?
Простите за сумбур.
bpg
новенький
 
Сообщения: 36
Зарегистрирован: 28.11.2017 21:23:18

Re: lazarus = Firebird - транзакции

Сообщение olegy123 » 18.04.2018 07:51:11

Посылай сигнал, а у клиентов обновляй таблицы с перезапуском транзакций.

Добавлено спустя 3 минуты 29 секунд:
с IBExpert у меня были тоже неприятные вещи.. попробуй другой инструмент.

Добавлено спустя 12 минут 46 секунд:
bpg писал(а):В голове у меня крутиться что-то такое. Если пользователь имеющий полномочия печатать справки, отчеты , договора и т.д. начал что то этакое делать, то всем программа должна послать какое то сообщение, что все теперь только readonly. И после формирование снова сообщение, продолжайте работать. Это как реализовать? Или все проще?
База тебе предлагает определенный функционал, не более того что написано в документации.. Online перевод подключенных клиентов из режима редактирования и в режим только чтения - я не встречал. Это очень частный случай, который требует дополнительных ветвлений - разработчики даже о них не думают.
Значит нужно этот функционал реализовать на клиенте. Можно сделать техзвенку..

bpg писал(а):делаю правку и никто эти данные не видит

делай состояние документа, создан/проверяется/проверен. Кнопка печать активизируется при статусе проверен.
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: lazarus = Firebird - транзакции

Сообщение alexs » 18.04.2018 12:42:19

bpg
Вообще тебе надо почитать для чего нужны транзакции и как с ними работать в FireBIrd
В общем случае тебе надо делать комит после каждого изменения данных в базе.
Это либо одна строка - либо несколько строк, но в любом не держи не подтверждённые транзакции вообще.
Оператор (девочка) что-то измененила - программа тут же делает комит.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: lazarus = Firebird - транзакции

Сообщение bpg » 18.04.2018 17:01:43

olegy123, alexs, и всем спасибо.
olegy123 писал(а):с IBExpert у меня были тоже неприятные вещи.. попробуй другой инструмент.
скорее всего был глюк.
olegy123 писал(а):делай состояние документа, создан/проверяется/проверен. Кнопка печать активизируется при статусе проверен.
хорошая идея, спасибо
alexs писал(а):Оператор (девочка) что-то измененила - программа тут же делает комит.
К этому и пришёл.

Добавлено спустя 4 минуты 42 секунды:
Со времен Delphi привык работать с БД в активном режиме при проектировании.
Т.е у меня Connection, Query и т.д. активны и я вижу данные в DBGrid например.
Не встречались ли у Вас при разработке в Lazarus глюки при таком подходе?
Может надо подключаться при запуске программы и меньше проблем будет? Может глючить из за этого?
bpg
новенький
 
Сообщения: 36
Зарегистрирован: 28.11.2017 21:23:18

Re: lazarus = Firebird - транзакции

Сообщение alexs » 18.04.2018 20:35:53

bpg писал(а):Не встречались ли у Вас при разработке в Lazarus глюки при таком подходе?

Всё точно также.
Недостаток - лишние запросы, тормоза.
Аватара пользователя
alexs
долгожитель
 
Сообщения: 4053
Зарегистрирован: 15.05.2005 23:17:07
Откуда: г.Ставрополь

Re: lazarus = Firebird - транзакции

Сообщение olegy123 » 19.04.2018 14:59:24

bpg писал(а):Может надо подключаться при запуске программы и меньше проблем будет? Может глючить из за этого?
В дизайн режиме, естественно данные ведут себя как в работе. Это значительно упрощает разработку.. Так что в дизайн - тоже включаются транзакции.
При запуске компоненты проходят инициализацию. и если в дизайн режиме было активно, то в реальном оно активизируется. Так же проще. Но не всегда правильно "в тяжелых работе".. Особенно когда нужно контролировать запуск поочередно. а при всех включенных - открытие формы может сильно тормозить программу.
Поэтому правильно тут отключать автоматизацию и переходить на ручник.
olegy123
долгожитель
 
Сообщения: 1643
Зарегистрирован: 25.02.2016 12:10:20

Re: lazarus = Firebird - транзакции

Сообщение bpg » 20.04.2018 21:01:53

olegy123Спасибо.
Кстати, тут на форуме вообще нет системы "спасибо" ? Или я ....? Искал не нашел, почти везде есть спасибо или рейтинг, оценки и т.д.
bpg
новенький
 
Сообщения: 36
Зарегистрирован: 28.11.2017 21:23:18

Re: lazarus = Firebird - транзакции

Сообщение bpg » 24.04.2018 12:55:58

Опять я со своей проблемой.
Сделал отлов эвентов, на добавление, изменение, удаление записи.
Все вроде работает. Запускаю одновременно 2 экземпляра программы и редактирую данные в одной, после сохранения данные меняются на обоих.
Но....
Как только меняешь картинку в blob поле она не обновляется. Хоть ты тресни. Опытным путем установил, что начинает работать если делать Connection false/true
т.е при изменении данных и Commit , Post, AplayUpdate , Refresh... все делаю, не помогает. Как будто картинка лежит в БД во временной таблице и не хочет обновляться, пока не сбросились буферы при переоткрытии коннекшена.
Но это же не выход? Или я не прав и можно так делать, после каждого POST? Просто тогда придеться заново инициализировать отлов эвентов и т.д.
И еще ...
Можно ли в post_event передавать id поля , которое было изменено или добавлено, чтобы сразу позиционировать пользователя на этой строке?
а если нельзя, то мне подсказывали что можно средствами БД оргпгизовать мини чат, а поподробнее можно?
Как именно это сделать, мне нужно только чтобы пользователи сетевые видели сообщение что изменилось строка номер такая то или удалилась или добавилась?
bpg
новенький
 
Сообщения: 36
Зарегистрирован: 28.11.2017 21:23:18

Re: lazarus = Firebird - транзакции

Сообщение Vadim » 25.04.2018 06:08:30

bpg писал(а):Как только меняешь картинку в blob поле

В блоб-поле Вашего датасета или всё же самого сервера? На сервер то картинка попала или нет?
Vadim
долгожитель
 
Сообщения: 4112
Зарегистрирован: 05.10.2006 08:52:59
Откуда: Красноярск

Re: lazarus = Firebird - транзакции

Сообщение 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 не работал.
MylnikovDm
постоялец
 
Сообщения: 103
Зарегистрирован: 15.02.2007 21:26:10
Откуда: Челябинск

Re: lazarus = Firebird - транзакции

Сообщение slyubez » 26.04.2018 18:06:33

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

Категорически не согласен.
Ссылки на изучение:
http://www.ibase.ru/ibtrans/
вместе со ссылками внутри статьи.

Добавлено спустя 4 минуты 49 секунд:
При просмотре всяческих списков и выборок из базы данных, это можно сделать через транзакцию в режиме READ COMMITTED, которая будет видеть все подтверждённые данные. Но тут нужно понимать, что данные становятся подтверждёнными именно в тот момент, когда завершается через commit та транзакция, через которую данные вносятся на сервер. То есть, если у вас девочка-оператор внесла данные в базу, но её транзакция в программе не была committed, то вы всё равно не сможете увидеть эти данные. Другими словами, если у вас в программе неправильно выстроена логика работы с транзакциями, то механизм сообщений (event'ов) вас всё равно не спасёт.

Не просто READ COMMITTED, a READ READ COMMITTED, то есть она Read only. Добавлю, что эта читающая транзакция может быть единственной на приложение. Однако есть у нее одна проблема - отжирание памяти при вычислительных операциях на сервере с BLOB-полями до коммита/роллбэка такой транзакции.
slyubez
постоялец
 
Сообщения: 173
Зарегистрирован: 31.03.2015 08:44:07

Re: lazarus = Firebird - транзакции

Сообщение MylnikovDm » 27.04.2018 11:50:35

Категорически не согласен.
Ссылки на изучение:
http://www.ibase.ru/ibtrans/
вместе со ссылками внутри статьи.

Во-первых, в статьях по ссылкам, которые вы привели, я не нашёл ничего, что противоречило бы моему утверждению: "Транзакция должна открываться в тот момент, когда вы хотите получить некий набор данных, после чего закрываться".
При этом во многих местах указывается на то, что длительно весящие транзакции, особенно с неправильно настроенными параметрами транзакции, вызывают те или иные проблемы работы сервера данных.

Во-вторых, я уже почти 20 лет работаю с разными SQL серверами и, исходя из личного практического опыта могу утверждать, что если в вашем приложении будет как можно меньше длительно весящих транзакций, тем меньше у вас будет проблем с данными, с их блокировкой и их несогласованностью. Но, если вы придерживаетесь другого мнения, то это ваше право. Не буду вас в этом переубеждать. Только при этом не надо забывать о том, что существуют ситуации, когда при выборке данных режим "read committed" не подходит, например, при выполнении сложных аналитических выборок для формирования различных отчётов, которые должны выполняться на фиксированном состоянии базы данных. Для подобных случаев чем меньше будет промежуток времени от начала транзакции до начала выборки данных с сервера, тем выше вероятность, что все актуальные данные попадут в формируемый отчёт.
MylnikovDm
постоялец
 
Сообщения: 103
Зарегистрирован: 15.02.2007 21:26:10
Откуда: Челябинск

Re: lazarus = Firebird - транзакции

Сообщение slyubez » 29.04.2018 23:05:11

Во-первых, в статьях по ссылкам, которые вы привели, я не нашёл ничего, что противоречило бы моему утверждению: "Транзакция должна открываться в тот момент, когда вы хотите получить некий набор данных, после чего закрываться".
При этом во многих местах указывается на то, что длительно весящие транзакции, особенно с неправильно настроенными параметрами транзакции, вызывают те или иные проблемы работы сервера данных.

Гораздо проще при старте приложения открыть читающую транзакцию, которая стартует уже в "закрытом" состоянии, и основное чтение вести через нее. Если транзакции постоянно закрывать при огромном количестве фетчей, можно добиться переполнения счетчика транзакций. Единственная ситуация, когда незакрытие транзакции вредно - это при формировании на сервере строк с участием текстовых BLOB-полей.

Только при этом не надо забывать о том, что существуют ситуации, когда при выборке данных режим "read committed" не подходит, например, при выполнении сложных аналитических выборок для формирования различных отчётов, которые должны выполняться на фиксированном состоянии базы данных.

Для таких ситуаций в Firebird есть режим транзакции SNAPSHOT.
slyubez
постоялец
 
Сообщения: 173
Зарегистрирован: 31.03.2015 08:44:07

Re: lazarus = Firebird - транзакции

Сообщение MylnikovDm » 02.05.2018 00:24:31

Гораздо проще при старте приложения открыть читающую транзакцию, которая стартует уже в "закрытом" состоянии, и основное чтение вести через нее.

Исходя из вашего ответа у меня возник5ают сомнения, что вы понимаете механизм работы транзакций. Можете привести пример того, как можно читать с сервера через "закрытую" транзакцию?

Что касается всего остального, то правильное проектирование общей логики работы приложения является залогом стабильной работы всей системы в целом. Само собой, что не имеет смысла постоянно открывать транзакцию на чтение данных, когда пользователь производит просмотр и выбор данных, которые отображаются через таблицы или списки, которые постепенно подгружаются с сервера. Но если использовать имеющийся в Lazarus компонент типа TDBGrid, то вы не сможете с ним работать по другому, поскольку большую часть операций по подгрузке данных с сервера он будет делать сам и с закрытой транзакцией работать не будет.

Кстати, рекомендую также внимательнее читать документацию к серверу FireBird. Транзакции типа Read Committed read, через которые рекомендуется в основном просматривать данные на сервере через те же TDBGrid, в принципе не удерживают версии и не изменяют счётчика транзакций. Там же рекомендуется основной поток чтения данных, в том числе чтение различных справочников, осуществлять через транзакцию с параметрами "read, read_committed, rec_version".
MylnikovDm
постоялец
 
Сообщения: 103
Зарегистрирован: 15.02.2007 21:26:10
Откуда: Челябинск

Re: lazarus = Firebird - транзакции

Сообщение slyubez » 02.05.2018 23:45:44

MylnikovDm писал(а):Исходя из вашего ответа у меня возник5ают сомнения, что вы понимаете механизм работы транзакций. Можете привести пример того, как можно читать с сервера через "закрытую" транзакцию?

В статье с ibase.ru про транзакции сказано:
Во всех последних версиях InterBase (6.0 и выше), Firebird и Yaffil, очень удобно для работы со справочниками стартовать транзакцию
read
read_committed
rec_version

Такая транзакция стартует в состоянии committed, поэтому не оказывает никакого влияния на sweep, версии и т. п., и поэтому может "жить" очень долго (сутками, месяцами...).

Раз транзакция стартует в состоянии committed, она завершена. Раз чтение через нее работает - вот и пример.

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

Многие разработчики не рекомендуют в принципе использовать DB-aware компоненты. Я сам предпочитаю подгружать данные в StringGrid или ListView, применяя при необходимости постраничную подгрузку, и редактировать записи в отдельном окне.
slyubez
постоялец
 
Сообщения: 173
Зарегистрирован: 31.03.2015 08:44:07

Пред.След.

Вернуться в Lazarus

Кто сейчас на конференции

Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 30

Рейтинг@Mail.ru