Главная страница
    Top.Mail.Ru    Яндекс.Метрика
Форум: "Базы";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];

Вниз

Обновлении данных в многопользовательских программах   Найти похожие ветки 

 
Vovovanych ©   (2004-05-11 08:58) [0]

Уважаемы Мастера! Вопрос об обновлении данных при многопользовательском использовании базы данных Interbase: имеется таблица, с которой очень активно работает десяток пользователей (добавляют, редактируют и удаляют записи). Как сделать (без повторного переоткрытия таблицы) чтобы у каждого пользователя была постоянно самая свежая и актуальная информация? Как считывать из базы именно добавленные или обновленные данные?


 
Anatoly Podgoretsky ©   (2004-05-11 09:04) [1]

Без переоткрытия?
Добавить timestamp


 
Sergey13 ©   (2004-05-11 09:29) [2]

2Vovovanych ©   (11.05.04 08:58)  
ИМХО, твои мечты из серии - "Миссия невыполнима".


 
Nikolay M. ©   (2004-05-11 09:38) [3]

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


 
stud ©   (2004-05-11 10:18) [4]

если пользователи активно работают с базой то большая часть времени будет уходить на обновление данных а нужно ли это?


 
Locker   (2004-05-11 11:36) [5]

2 Vovovanych
Творите, выдумывайте, пробуйте... Решения задачи есть.
Вариант 1. Использование в каждой записи поля "Время последнего обновления". И выборка по этому полю. (Никогда не пробовал - может, и есть смысл, но, при большом количестве таблиц в проекте, будут тормоза с перебором таблиц).
Вариант 2. Использование таблицы синхронизации, в которую, при каждом изменении в других таблицах, вносится имя измененной таблицы и ключ записи. Кроме этого нужно автоинкрементное поле - для того, чтобы знать, с какой записи читать новые данные о синхрониации. И еще - таймер.

2 Sergey13
Не умеете сами - не мешайте другим...

2 stud

Сколько времени нужно на выборку одной записи из таблицы с миллионом записей? Посчитайте - и поймете, что синхронизация - это лучше, чем ручное обновление всей таблицы: быстрее, незаметнее и траффик низкий.

2 Nikolay M.
Объясните, почему это не нужно?


 
Курдль ©   (2004-05-11 11:42) [6]


> Locker   (11.05.04 11:36) [5]

Примените к себе свой же совет, который адресовали Sergey13
Автору не интересно знать, когда-что было обновлено, а надо рассылать Event-ы клиентам, как только что-то обновилось. Этим занимаются и вправду тяжеловесные, и чаще всего не оправдывающие себя Application-серверы, либо некоторые DB-серверы. Главное для него - определить, насколько это нужно пользователям. Лично я, не зная бизнесс-процессов, за решение не возьмусь.


 
Desdechado ©   (2004-05-11 11:48) [7]

2 Locker
вот пользователь редактирует запись, а ему автоматически раз - и обновили ее. вот матюки будут...

и что, для каждой записи свой запрос на проверку обновления? для выборки из 200 строк - 200 запросов? тормоза обеспечены, особенно если это с интервалом в 1 мин делать.

а про миллион загнул - никто на клиенте с таким количеством не работает


 
Sergey13 ©   (2004-05-11 11:48) [8]

2Locker   (11.05.04 11:36) [5]
А вы братец - хам. Именно потому что знаю как это делается и говорю, что при поставленых условиях задача невыполнима. Выполнима, но с большими затратами при других условиях. Но в любом случае проблема надумана и реализовывать ее не стОит. Никому это не надо. Достаточно одной кнопки "Обновить".
А твои советы - ну от Locker-а чего еще ждать. 8-)


 
div ©   (2004-05-11 11:53) [9]

(ИМХО) использовать на всех клиентах транзакции no_rec_version. Однако я уверен что при этом возникнут проблемы с блокировками записей. Видимо нужно использовать в транзакции параметр wait. Что касается Event"ов - то если работа действительно интенсивная, и при каждом изменении/удалении производить обновление - то думаю что как минимум половина пользователей только и будут делать что ждать обновления данных. Поэтому думаю стоит зделать обновление либо "вручную", либо по таймеру (например раз в минуту, это зависит от объемов).


 
Erik ©   (2004-05-11 12:28) [10]

Чего за фигня, я сделал обновление и все работает. У меня AppServer смотрит нужно ли пользователю обновление, если нужно вызывает CallBack передавая имя таблицы на клиента. Клиент смотрит какие формы подписались на даное событие и вызывает их метод обновления. Правда необходимось в обновлении у меня возникает не часто.


 
Danilka ©   (2004-05-11 12:36) [11]

Как я люблю этот вопрос! :))

[10] Erik ©   (11.05.04 12:28)
Интересно, а как он узнает - нужно пользователю обновление или нет? Например, пользователь утром запустил приложение, открыл все формы какие есть и пошел кофу попить, а потом водки, и весь день АппСервер думает что пользователю нужно обновление?


 
Locker   (2004-05-11 12:44) [12]

2 Sergey13
Прежде чем обвинять кого-то в хамстве - найдите повод обвинять!

Задача: Есть список (таблица) клиентов - физических лиц. В таблице - 50000 записей. Добавляем нового клиента. Скажем, 100 новых клиентов в день.
Вопрос: Как другим пользователям узнать, что в БД добавлен новый клиент? Обновлять все 50000 записей (хм...)? Или только запросить из БД новую запись? И как это сделать? Что проще: по 1 результирующей строке в запросе обновления, или по 50000 строк в каждом "ручном обновлении" кнопкой?

2 Desdechado
>> вот пользователь редактирует запись, а ему автоматически раз - и обновили ее
Для таких случаев в Pascal"e есть условный оператор:
if (not DataSet.State in [dsEdit, dsInsert]) then
begin
 // обновление
end;


 
Nikolay M. ©   (2004-05-11 12:52) [13]


> 2 Nikolay M.
> Объясните, почему это не нужно?

Потому что по большому счету я согласен с [2].
Тема поднималась уже раз 100, наверное. Пока было предложено единственно правильное решение - обновлять запрос по нажатию юзером кнопки. Все остальное - от лукавого.

ПС
Кстати, тут прозвучали мысли о посылке апп-сервером клиентам сообщения, что нужно обновиться. Гораздо логичнее, имхо, рассылать собственно изменения, а не заставлять кучу юзеров ломиться рефрешить свои данные. Собственно, я об этом сказал еще в [3].


 
Mike Kouzmine ©   (2004-05-11 12:53) [14]

Locker   (11.05.04 12:44) [12] А зачем им это узнавать? Добавили и добавили, слава Аллаху!


 
Danilka ©   (2004-05-11 12:53) [15]

[12] Locker   (11.05.04 12:44)
Гы.
Ну давай возьмем твой надуманый пример. Конктретно вопрос.


> Как другим пользователям узнать, что в БД добавлен новый
> клиент?

А нафига? Нафига им узнавать что добавлен новый клиент?
Ну заполняю я, к примеру, счет-фактуру, выбираю клиента из списка клиентов, при этом на момент выбора клиента идет запрос к серверу.
Момент времени, при котором я открываю список клиентов, ищу того, который мне нужен и выбираю его в СФ очень короткий. Даже если за этот момент и появился новый клиент - он мне по-барабану.

> Обновлять все 50000 записей (хм...)?

Вообще, тянуть столько записей на клиента - грех.


 
Danilka ©   (2004-05-11 13:11) [16]

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


 
Desdechado ©   (2004-05-11 13:23) [17]

[12] Locker
гы, ладно, внес изменения, запостил, но в БД не сохранил - что здесь, а?


 
VoVovanych ©   (2004-05-11 16:32) [18]

Тпру... Стойте, остановитесь. Не думал что мой вопрос вызовет такую бурю эмоций. Тем более разбирательств "хам-нехам" :) Я возможно не совсем корректно задал вопрос: возможно ли получить в УЖЕ ОТКРЫТЫЙ запрос запись, добавленную другим пользователем, тем более что необходимость в актуальных данных имеется (привести полностью постановку задачи не могу, долго и нудно)? Пробовал использовать FIBPlus (ОГРОМНОЕ СПАСИБО Сергею БУЗАДЖИ, обещаю купить лицензионку), там есть компонент FIBDataSet и у него метод Refresh, который автоматически после вставки или удаления обновляет именно ту запись, в которой произошли изменения (естественно не на всех машинах, а на той где эти изменения и произошли :)). Кто не знаком с FIBDataSet хочу пояснить что запрос на обновление выглядит примерно так: Select X From Y Where Z=:OLD_ID (ID ключевое поле таблицы). То есть при редактировании, точнее после редактирования, вызывается этот самый запрос, в котором параметру OLD_ID присваивается значение ID той самой отредактированной записи и соответственно обновляется только эта запись. Уф-ф-ф-ф... Надеюсь понятно объяснил. Так вот, я пробовал сделать так: приложение получало от сервера сообщение о том что добавлена или изменена запись, передавался ID записи, я пытался передать этот ID в запрос как OLD_ID (примерно так qryAAA.ParamByName("OLD_ID").As Integer:=ID) и вызвать Refresh... Безрезультатно :(  Получаю ошибку что-то типа "Параметр OLD_ID не существует". Как насчет такого варианта развития события?

2Sergey13 В данный момент у меня стоит кнопка "Обновить"... Многим не нравиться, да и не помогает: рефрешатся каждую минуту...

2Anatoly Podgoretsky: Часто читаю Ваши ответы и они помогают. Единственная проблема - краткие они очень :)... Если можно, разъясните несколько подробней. Разжевывать не надо, просто нарежьте :)))


 
Курдль ©   (2004-05-11 17:23) [19]

Боюсь, что никакие FIBDataSet-ы с обновлением одной записи Вам не поможет, т.к. он вернет ее только Вам же, а не всем юзерам.


 
Petr V. Abramov ©   (2004-05-11 18:52) [20]

> рефрешатся каждую минуту...
 Либо у них нету возможностей поиска
 Либо постановка задачи нехорошая
 Либо это действительно надо (1% вероятности). Тогда либо event`ы, либо AppServer какой-нить масти


 
AGin   (2004-05-11 19:23) [21]

2 VoVovanych Мне кажется, что в Вашем случае поможет несколько извращенное решение - использовать обычные GRID"ы (НЕ DBGRID"ы) для отображения информации (или другие контролы). Тогда от пользователя будет скрыта вся внутренняя работа программы по обновлению данных. А данные следует обновлять, как советовал А.Подгорецкий (и другие) - в каждую нужную таблицу добалять поле timestamp и раз в минуту просматривать ID отредактированных за эту минуту записей. При наличии таковых - обновлять информацию в GRID"ах ВРУЧНУЮ. Это, конечно, геморрой, но не очень большрй...:))


 
Anatoly Podgoretsky ©   (2004-05-11 19:45) [22]

VoVovanych ©   (11.05.04 16:32) [18]
Как считывать из базы именно добавленные или обновленные данные?

Anatoly Podgoretsky ©   (11.05.04 09:04) [1]
Добавить timestamp

Без временной метки это не возможно сделать, ты никак не отличишь обновленную от необновленной. Каждая запись в таблицу должна делаться с обновленной меткой, тогда в запросе можно будет указать TS>OldTS, вернутся все новые и обновленные


 
VoVovanych ©   (2004-05-11 21:58) [23]

2 Курдль: не совсем. Каждое запущенное приложение получает от сервера сообщение и запускает у себя процедуру обновления данных. Теоретически это задумывалось так :). Практически не получилось. Так и родился сабж...

2 Petr V. Abramov ©: Возможность поиска есть, причем настолько навороченная, что лучше уж по моему быть не может (просьба не изголятся по поводу навороченности, не тратьте время) :) Просто для оперативного решения вопросов необходимо видеть ВСЁ...

2 ВСЕМ: попытка №3. Отвлечемся от постановки задачи, кнопок принудительного обновления, timestampов, правильно-неправильно и т.д. Будем считать что мы знаем какие записи нужно обновить (добавить и т.д.). ЗАДАЧА: КАК В УЖЕ ОТКРЫТЫЙ ЗАПРОС ПОЛУЧИТЬ С СЕРВЕРА НОВЫЕ (ОБНОВЛЕННЫЕ) ДАННЫЕ? То ли лыжи у меня не едут, то ли одно из двух.


 
Polevi ©   (2004-05-11 23:02) [24]

запросить эти данные во временный датасет, ручкам пробежать по нему и обновить рабочий сет
еснно нужно ключевое поле для сопоставления записей


 
Petr V. Abramov ©   (2004-05-11 23:05) [25]

CachedUpdates = true
 отдельный запрос обновлений (пусть qrRefresh) по таймеру или по event`ам
 ручная перекачка записей из qrRefresh в основной
 возможно, еще геморрой с соблюдением сортировки


 
Курдль ©   (2004-05-11 23:20) [26]


> VoVovanych ©   (11.05.04 21:58) [23]
> (добавить и т.д.). ЗАДАЧА: КАК В УЖЕ ОТКРЫТЫЙ ЗАПРОС ПОЛУЧИТЬ
> С СЕРВЕРА НОВЫЕ (ОБНОВЛЕННЫЕ) ДАННЫЕ? То ли лыжи у меня
> не едут, то ли одно из двух.

Вы достаточно тертый калач, но ленитесь! Для себя бы я чё-нить придумал (пока что просто таких ТЗ не попадалось) а для Вас - тоже лень :)
Ну есть идея (в предсонном бреду) создать журнал логов на значимые таблицы и "вести" в нем по триггерам изменения значимых полей. Отдельным запросом порлучать свежие данные, обрабатывать на клиенте по принципу "это у нас уже есть, а это, ты глянь,  - изменилось!". А потом насильственно записывать в набор данных обработанные изменения.
И далее - давайте по понятиям! Что есть "ОТКРЫТЫЙ ЗАПРОС"? Видимо "ПОЛУЧЕННЫЙ НАБОР ДАННЫХ"?


 
Polevi ©   (2004-05-11 23:27) [27]

> [26] Курдль ©   (11.05.04 23:20)
скорее всего открытый запрос у него квери в гриде отображается и он не хочет целиком перезапрашивать его, имеет смысл в принципе если большая выборка и реализован эффективный механизм уведомлений об изменениях, хотя это не просто.. много холостых данных и проблема с редактированием, о чем уже говорилось
хотя при желании можно конечно сделать, проблему холостых данных можно решить через подписку на события об изменениях и отписываться в случае если юзер не работает с программой..
мое имхо лучше без этого обойтись


 
Курдль ©   (2004-05-11 23:34) [28]

Да просто может не следует комплексоваться на избранной структуре? Ведь решений может быть немеряно! Уже 100 раз говорили об application server. Да взять какой-нить апач на сервер, забульбенить логику на сервлетах Java, а юзерам - апплеты через браузер (заодно проблема вэб-доступа сразу решится, а то ее в ТЗ всегда как "перспективную фитчу" прописывают :)


 
Polevi ©   (2004-05-11 23:39) [29]

да с app-server тоже не фонтан
проблема в том что нефиг качать данные туда-сюда когда их никто не ждет


 
Курдль ©   (2004-05-11 23:44) [30]


> проблема в том что нефиг качать данные туда-сюда когда их
> никто не ждет

Если он так упорно настаивает на том, что надо, значит кто-то ждет. Другое дело, что вряд ли следует привязываться к стандартным принципам работы с БД. Например, через сокеты транслировать все обновления "бегущей строкой" от сервака к клиентам (как сделки на бирже) а там уж каждый клиент по наборам данных раскладывает...


 
SteelAxe   (2004-05-12 04:04) [31]

2VoVovanych ©   (11.05.04 21:58) [23]CachedUpdates = true
1.Получаешь с сервака набор, открываешь(запуск программы).
2.редактируешь датасет в соответствии с AppEvents.
3.Если ТЕКУЩИЙ клиент редактирует запись, то ВЫВОДИШЬ ЗАПИСЬ В   ОТДЕЛЬНОЕ ОКОШКО и пусть он там её себе редактирует. При сохранении этой записи отсылаешь ОТДЕЛЬНЫЙ запрос-сохранение на сервер И В СВОЙ ОТКРЫТЫЙ ДАТАСЕТ со значениями, считанными с ЭТОГО ОКОШКА.
4.В конце работы закрываешь датасет без сохранения сделанных изменений.
Здесь кратко, но, думаю, понятно. Надеюсь подойдёт.


 
VoVovanych ©   (2004-05-13 07:14) [32]

Спасибо всем кто ответил. Вариантов предложена куча, есть над чем подумать. Еще раз спасибо.



Страницы: 1 вся ветка

Форум: "Базы";
Текущий архив: 2004.05.30;
Скачать: [xml.tar.bz2];

Наверх





Память: 0.55 MB
Время: 0.04 c
3-1083821859
Mamed
2004-05-06 09:37
2004.05.30
get database name


4-1081638815
Gott
2004-04-11 03:13
2004.05.30
Уникальное сообщение


3-1083930785
Внук
2004-05-07 15:53
2004.05.30
ODBC и хранимые функции


11-1073933570
Phantomaz
2004-01-12 21:52
2004.05.30
Как поменять шрифт и цвет текста Item ов в PopupMenu ?


3-1083919987
lockheed_man
2004-05-07 12:53
2004.05.30
Проблемы с сохранением если не все поля грида заполнены





Afrikaans Albanian Arabic Armenian Azerbaijani Basque Belarusian Bulgarian Catalan Chinese (Simplified) Chinese (Traditional) Croatian Czech Danish Dutch English Estonian Filipino Finnish French
Galician Georgian German Greek Haitian Creole Hebrew Hindi Hungarian Icelandic Indonesian Irish Italian Japanese Korean Latvian Lithuanian Macedonian Malay Maltese Norwegian
Persian Polish Portuguese Romanian Russian Serbian Slovak Slovenian Spanish Swahili Swedish Thai Turkish Ukrainian Urdu Vietnamese Welsh Yiddish Bengali Bosnian
Cebuano Esperanto Gujarati Hausa Hmong Igbo Javanese Kannada Khmer Lao Latin Maori Marathi Mongolian Nepali Punjabi Somali Tamil Telugu Yoruba
Zulu
Английский Французский Немецкий Итальянский Португальский Русский Испанский