Конференция "Базы" » Обновление одного DBGrid разными клиентами [D7, FireBird 1.5]
 
  • CleriC (08.04.13 09:44) [0]
    Здравствуйте.
    Что-то я совсем запутался, перерыл кучу информации, вообщем тупик.
    Есть база firebird 1.5 для соединения с ней клиенты используют embeded сервер (fbclient.dll).
    Создано оконное приложение в Delphi 7, к DBGrid подключена таблица. К FIBDataBase подключено 2 транзакции: длинная читающая и пишущая (короткая).
    Каждый клиент может редактировать эту таблицу, но второй клиент почему-то не видит изменения, которые внес первый клиент.
    Хотя уровень изоляции читающей транзакции ReadCommited, так что, вроде как, видеть то изменения клиент должен. Коммит в пишущей трнзакции делается автоматом.
    Если я закрываю датасет и снова открываю - изменения появляются. Но даже если я делаю Refresh датасета - изменений все равно нет.
    Почему такое может быть и где я могу допустить ошибку?
  • Sergey13 © (08.04.13 10:16) [1]
    >Есть база firebird 1.5 для соединения с ней клиенты используют embeded сервер (fbclient.dll).
    Это как? Эмбеддед - это не "для соединения". Это собственно сервер БД, но работает он только тогда, когда есть к нему обращения. Потому и эмбеддед.

    > к DBGrid подключена таблица
    Вся таблица? Или запрос по части таблицы? Вообще идеологически правильнее второе.

    >но второй клиент почему-то не видит изменения, которые внес первый клиент.
    А задача второго следить за первым?

    >Если я закрываю датасет и снова открываю - изменения появляются.
    Это нормальное поведение: хочешь увидеть новое состояние - перечитай данные.
  • CleriC (08.04.13 10:40) [2]

    > А задача второго следить за первым?

    Задача на каждом клиенте видеть актуальные данные. То что сделано (и подтверждено) одним клиентом должно быть увидено всеми остальными.


    > Это нормальное поведение: хочешь увидеть новое состояние
    > - перечитай данные.

    Вот в этом я и хочу разобраться. Начал читать про изоляции транзакции, вроде как ReadCommited это то что мне нужно. То что подтверждено на других клиентах должны увидеть остальные. Но этого не происходит. То ли я не правильно понял как работают транзакции, то ли делаю что-то не то, то ли единственный способ увидеть изменения - закрывать и вновь открывать датасет. Но даже в ведь даже этом случае Refresh должен помогать?
  • Плохиш © (08.04.13 11:01) [3]

    > То что подтверждено на других клиентах должны увидеть остальные.
    >  Но этого не происходит.

    Что бы увидеть новые данные "остальные" должны "закрывать и вновь открывать датасет".

    > Но даже в ведь даже этом случае Refresh должен помогать?

    Странно, откуда такие выводы? Даже в описании этого метода таких гарантий не дают.
  • Sergey13 © (08.04.13 11:06) [4]
    >Задача на каждом клиенте видеть актуальные данные.
    В 99% случаев - это не задача, а ошибочное видение задачи программистом/заказчиком. Хочешь пообсуждать этот вопрос - описывай свою задачу.

    >То что подтверждено на других клиентах должны увидеть остальные.
    Они и увидят, когда запросят информацию в следующий раз, т.е. после переоткрытия.
    Refresh - возможно просто не реализован в твоих компонентах доступа. Но скорее всего, что бы его реализовать нужно все равно перечитать данные, а это Close-Open.
  • CleriC (08.04.13 11:28) [5]
    Моя задача: есть база, где хранятся данные о заказах (что было продано, сколько и кому). База лежит на сервере. Я пишу клиентское приложение, которое берет информацию из базы и предоставляет ее пользователю для просмотра и редактирования (использую FIB+). С базой работает несколько человек и хотелось бы что бы данные, внесенные одним, были сразу видимы остальным.
    Сделать это через переоткрытие датасета несложно. Но я думал что для этих целей существуют уровни изоляции транзакции. Для чего существует транзакция ReadCommited? То поведение которое я вижу, относится к Snapshot транзакции.

    Но Refresh то должен помогать! По крайней мере это звучит из описания:
    Метод Refresh повторно читает весь TDataSet. Обращаться к Refresh следует, когда TDataSet изменяется программно или какой-то другой процесс изменяет данные, отображаемые или используемые приложением. [...]
    Обращение к Refresh гарантирует предоставление текущих данных на момент вызова. Refresh можно использовать периодически для обеспечения текущих данных.

    http://www.az-design.ru/index.shtml?Support&SoftWare&Delphi/D3/SB36Refresh

  • clickmaker © (08.04.13 11:31) [6]
    > То что сделано (и подтверждено) одним клиентом должно быть
    > увидено всеми остальными

    ты же на этом форуме не видишь автоматом, что тебе наотвечали. Нужно нажать ф5 или перевойти в тему. Но создатель сайта мог бы в заголовке настроить meta refresh, чтобы страница сама перезагружалась через определенный интервал.
    Так же и с датасетом. Можно настроить периодическое обновление по таймеру. Есть еще вариант подписки на обновления со стороны сервера, но это усложняет архитектуру в целом, да и оказывается, что в большинстве случаев это нафик никому не надо.
    Если юзер хочет быть уверен, что работает с актуальными данными, надо их явно или неявно запросить. По такому принципу работают все системы контроля версий, например.
  • clickmaker © (08.04.13 11:34) [7]
    > Для чего существует транзакция ReadCommited?

    транзакции не имеют отношения к поддержке актуальности данных на клиенте.
    http://ru.wikipedia.org/wiki/%D0%A3%D1%80%D0%BE%D0%B2%D0%B5%D0%BD%D1%8C_%D0%B8%D0%B7%D0%BE%D0%BB%D0%B8%D1%80%D0%BE%D0%B2%D0%B0%D0%BD%D0%BD%D0%BE%D1%81%D1%82%D0%B8_%D1%82%D1%80%D0%B0%D0%BD%D0%B7%D0%B0%D0%BA%D1%86%D0%B8%D0%B9
  • CleriC (08.04.13 12:06) [8]
    Спасибо за ответы, насчет обновления датасета понял, буду переоткрывать.
    Но для чего же все-таки существует метод Refresh?
  • clickmaker © (08.04.13 12:26) [9]
    > для чего же все-таки существует метод Refresh?

    зайди отладчиком, посмотри исходники. Он может быть переопределен у наследника TDataSet, но может и не работать, о чем в справке и написано:
    Note: The Refresh method does not work for all TDataSet descendants. In particular, TQuery components do not support the Refresh method if the query is not "live". To refresh a static TQuery, close and reopen the dataset.
  • Leshiy_ (09.04.13 11:13) [10]

    > Метод Refresh повторно читает весь TDataSet. Обращаться
    > к Refresh следует, когда TDataSet изменяется программно
    > или какой-то другой процесс изменяет данные...

    DataSet <> файл базы данных
 
Конференция "Базы" » Обновление одного DBGrid разными клиентами [D7, FireBird 1.5]
Есть новые Нет новых   [119469   +73][b:0][p:0.001]