ZeosDBO + Firebird кэширование?

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

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

ZeosDBO + Firebird кэширование?

Сообщение wofs » 18.09.2017 12:44:54

Доброго всем дня.
Движемся дальше. Для своей утилиты я выбрал БД FireBird. Это мой первый опыт работы с данной БД.
В качестве компонента доступа решил использовать немного знакомый ZeosDBO(TZConnection+TZQuery+TDataSource).
На тестах выявилась одна проблема - если с таблицей работают 2 одновременно открытых соединения (версия FireBird 2.5 не embedded), то изменения таблицы в рамках одного соединения видны в другом только, если закрыть и заново открыть второе соединение - просто повторный запрос не дает результата. Я догадываюсь, что дело в кэшировании результата запроса, но не знаю что делать - подскажите, пожалуйста.
Простое
Код: Выделить всё
with ZConnection2 do
begin
Connected:=false;
Connected:=true;
end;

перед повторным запросом конечно решает проблему, но результатом я не доволен.
--
Если догадка моя про кэширование верна, то как мне отключить кэширование результатов запроса для конкретного запроса?
Аватара пользователя
wofs
постоялец
 
Сообщения: 211
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: ZeosDBO + Firebird кэширование?

Сообщение Лекс Айрин » 18.09.2017 13:47:04

Скорее, сбросить кеш на сервер.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4175
Зарегистрирован: 19.02.2013 16:54:51

Re: ZeosDBO + Firebird кэширование?

Сообщение vada » 18.09.2017 16:05:47

Обычно помогаю BEGIN TRANSACTION, COMIT, ROLBAK ...
Аватара пользователя
vada
энтузиаст
 
Сообщения: 650
Зарегистрирован: 14.02.2006 13:43:17

Re: ZeosDBO + Firebird кэширование?

Сообщение wofs » 18.09.2017 17:42:51

vada писал(а):Обычно помогаю BEGIN TRANSACTION, COMIT, ROLBAK ...

Не понимаю, причем здесь транзакции - просветите, если не сложно.
Код: Выделить всё
ZConnection.AutoCommit:=true;

Равно как и
Код: Выделить всё
ZConnection.AutoCommit:=false;
...
ЗАПРОС
ZConnection.Commit;


Лекс Айрин писал(а):Скорее, сбросить кеш на сервер.

Ок, почитаю, спасибо.

Я так понял нужно что-то вроде
Код: Выделить всё
SQL_NO_CACHE
, но для Fidebird.
Последний раз редактировалось wofs 18.09.2017 17:58:37, всего редактировалось 1 раз.
Аватара пользователя
wofs
постоялец
 
Сообщения: 211
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: ZeosDBO + Firebird кэширование?

Сообщение Лекс Айрин » 18.09.2017 17:58:17

wofs писал(а):Не понимаю, причем здесь транзакции - просветите, если не сложно.


Транзакция, это полностью завершенный набор операций.

Если какое-то из действий не совершено, то транзакция считается не совершенной и все проделанные операции откатываются.
По завершении транзакции действия в локальной копии БД должны быть синхронизированы с удаленной БД. Т. к. разрушение БД может привести к большим проблемам, то для ее изменения и применяются транзакции, которые гарантируют целостность БД. Т. е. пока транзакция не завершена изменения могут быть в любой момент удалены, без разрушения(повреждения) БД. Даже если оборвется соединение или сервер будет грубо выключен.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4175
Зарегистрирован: 19.02.2013 16:54:51

Re: ZeosDBO + Firebird кэширование?

Сообщение wofs » 18.09.2017 18:01:18

Лекс Айрин писал(а):Транзакция, это полностью завершенный набор операций.

Разве при настройке
Код: Выделить всё
ZConnection.AutoCommit:=false;

И коммите после запроса добавления записи
Код: Выделить всё
ZConnection.Commit;

я не завершаю транзакцию?

И у меня проблема в том, что я не могу увидеть изменения, сделанные в рамках первого коннекта - во втором коннекте, пока этот самый второй коннект не "передерну", что меня решительно не устраивает.
Последний раз редактировалось wofs 18.09.2017 18:19:53, всего редактировалось 1 раз.
Аватара пользователя
wofs
постоялец
 
Сообщения: 211
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: ZeosDBO + Firebird кэширование?

Сообщение Лекс Айрин » 18.09.2017 18:17:39

wofs писал(а):И у меня проблема в том, что я не могу увидеть изменения, сделанные в первом коннекте - во втором коннекте, пока этот самый второй коннект не "передерну", что меня решительно не устраивает.


Вопрос на засыпку -- как этот второй коннект узнает, что БД изменилась? По идее, у тебя должен стоять по таймеру запрос актуальности данных. Ну или не по таймеру, а при совершении каких-либо серьезных телодвижений.

wofs писал(а):я не завершаю транзакцию?


А это надо смотреть как реализовано. В общем случае скорее нет. Ты инициируешь завершение. Само завершение происходит после выхода из этого метода. Нюанс тонкий, но он есть.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4175
Зарегистрирован: 19.02.2013 16:54:51

Re: ZeosDBO + Firebird кэширование?

Сообщение wofs » 18.09.2017 18:21:49

Лекс Айрин писал(а):Вопрос на засыпку -- как этот второй коннект узнает, что БД изменилась?

А зачем второму коннекту знать изменилось что-то или нет в БД.
Я делаю в рамках второго коннекта повторный запрос:
Код: Выделить всё
with ZQuery2 do
begin
close;
SQL.Text:='SELECT * FROM TABLE';
open;
end;

И не вижу изменений, сделанных ранее в первом коннекте, но если сделать:
Код: Выделить всё
with ZConnection2 do
begin
Connected:=false;
Connected:=true;
end;

И потом:
Код: Выделить всё
with ZQuery2 do
begin
close;
SQL.Text:='SELECT * FROM TABLE';
open;
end;

то все ок.

Притом я не трогаю первый коннект (ZConnection1) - он так и висит активным.

Добавлено спустя 17 минут 5 секунд:
Нашел решение:
Код: Выделить всё
ZConnection.TransactIsolationLevel:=tiReadCommitted;

На мысль натолкнуло это:
https://msdn.microsoft.com/ru-ru/library/ms173763(v%3Dsql.120).aspx
Теперь ищу причину, по которой пришлось так сделать....
Последний раз редактировалось wofs 18.09.2017 18:46:16, всего редактировалось 1 раз.
Аватара пользователя
wofs
постоялец
 
Сообщения: 211
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: ZeosDBO + Firebird кэширование?

Сообщение Лекс Айрин » 18.09.2017 18:43:52

wofs писал(а):А зачем второму коннекту знать изменилось что-то или нет в БД.


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

Это все делается для того чтобы не гонять постоянно гигабайты ненужной инфы туда-сюда.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4175
Зарегистрирован: 19.02.2013 16:54:51

Re: ZeosDBO + Firebird кэширование?

Сообщение pupsik » 18.09.2017 18:48:29

На мысль натолкнуло это:
ну ещё, для размышления, вопрос: сколько транзакций открывает птичка при запросе "только на чтение".
pupsik
энтузиаст
 
Сообщения: 1017
Зарегистрирован: 20.08.2014 16:20:13

Re: ZeosDBO + Firebird кэширование?

Сообщение wofs » 18.09.2017 18:52:43

pupsik писал(а):ну ещё, для размышления, вопрос: сколько транзакций открывает птичка при запросе "только на чтение".

Я думаю что одну на каждый запрос, если не указано иное.
Аватара пользователя
wofs
постоялец
 
Сообщения: 211
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: ZeosDBO + Firebird кэширование?

Сообщение vada » 18.09.2017 18:57:16

Я делаю в рамках второго коннекта повторный запрос
И не вижу изменений, сделанных ранее в первом коннекте

Это и говорит о незавершенной транзакции. Пока она не завершена, второй клиент не увидит изменений, хоть 100500 раз селект делай.
А то что второй клиент видит изменения после реконнекта, ну... этому несколько причин может быть. Самое, что лежит на поверхности, это буферизация запросов второго клиента. Что-то там не так. Может в настройках у вас отложенный комит. Может вложенные транзакции, и пока самая верхняя не завершена не видно изменений. Как работает доступ к СУБД в лазарусе не имею представления. Потом, разные СУБД работают поразному. Я много лет работал с постгресом. Клиентов около сотни, 8 ролей доступа, три удаленных офиса со своими серверами и репликацией. Но вот такой фигни ни разу не было. Может потому что работал через Tomcat или JBOSS. Были только задержки на репликацию. Т.е. производство не мгновенно видело задание от удаленных офисов, да им это и не нужно было.
Аватара пользователя
vada
энтузиаст
 
Сообщения: 650
Зарегистрирован: 14.02.2006 13:43:17

Re: ZeosDBO + Firebird кэширование?

Сообщение wofs » 18.09.2017 18:59:14

vada писал(а):Это и говорит о незавершенной транзакции. Пока она не завершена, второй клиент не увидит изменений, хоть 100500 раз селект делай.

Да, но установка
Код: Выделить всё
ZConnection.TransactIsolationLevel:=tiReadCommitted;

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

Добавлено спустя 3 минуты 2 секунды:
Притом работает только при
Код: Выделить всё
ZConnection.AutoCommit:=false;

и когда я делаю принудительно после каждого изменения таблицы
Код: Выделить всё
ZConnection.Commit;


Добавлено спустя 8 минут 13 секунд:
А то, что по умолчанию было очень похоже на поведение
Код: Выделить всё
tiRepeatableRead

тогда возникает вопрос - как в ZeosDBO + Firebird перед запросом чтения принудительно стартовать новую транзакцию?
Код: Выделить всё
_Connect.StartTransaction;

Никак не решило проблему.
Последний раз редактировалось wofs 19.09.2017 18:29:53, всего редактировалось 1 раз.
Аватара пользователя
wofs
постоялец
 
Сообщения: 211
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

Re: ZeosDBO + Firebird кэширование?

Сообщение Лекс Айрин » 18.09.2017 19:11:58

все правильно.

сначала ты запрещаешь автоматическое сохранение, а потом сохраняешь вручную. При том, что неизвестно когда программа захочет сохранить изменения на сервер.
wofs писал(а):значит проблема не в незавершеной транзакции, в рамках которой писались данные - это как минимум. Или я не прав?


Не факт. Ты мог видеть данные незавершенных транзакций.
Аватара пользователя
Лекс Айрин
долгожитель
 
Сообщения: 4175
Зарегистрирован: 19.02.2013 16:54:51

Re: ZeosDBO + Firebird кэширование?

Сообщение wofs » 18.09.2017 19:14:25

Лекс Айрин писал(а):сначала ты запрещаешь автоматическое сохранение, а потом сохраняешь вручную.

При том же раскладе без
Код: Выделить всё
ZConnection.TransactIsolationLevel:=tiReadCommitted;

Я получаю ровно тот результат, из-за которого я сюда и пришел.
Аватара пользователя
wofs
постоялец
 
Сообщения: 211
Зарегистрирован: 05.10.2009 10:16:55
Откуда: Астрахань

След.

Вернуться в Lazarus

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

Сейчас этот форум просматривают: Yandex [Bot] и гости: 5

Рейтинг@Mail.ru