Xpoint
   [напомнить пароль]

Передача уведомлений между клиентами

Метки: [без меток]
2007-04-02 19:50:19 [обр] Хаврах[досье]

Есть такая ситуация: SQL-сервер (неважно какой), SQL-клиент 1 и SQL-клиент 2. Клиент 1 эпизодически добавляет (INSERT) в таблицу данные, клиент 2 хочет получать уведомления при каждом таком INSERT'е. Клиенты физически находятся на разных машинках.

Вопрос: Как взрослые люди решают такую задачу?

Я нашел решение через GET_LOCK/RELEASE_LOCK (я использую MySQL), но оно мне кажется, мягко говоря, кривым. Какие еще могут быть варианты?

спустя 17 часов [обр] Валера(0/24)[досье]
клиент 2 хочет получать уведомления при каждом таком INSERT'е
Что имеется ввиду под уведомлением? Если я правильно понял вы хотите чтобы при вставке записей у одного пользователя, к другому приходило уведомление об этом? И еще, вы хотите сделать это средствами SQL? Честно говоря не понял при чем тут GET_LOCK() и RELEASE_LOCK(), AFAIK они используются для блокировки на уровне пользователя.
спустя 4 часа 12 минут [обр] Хаврах[досье]

Уведомление - любая информация сигнализирующая о произошедшем INSERT'е.

С локами просто: GET_LOCK() возвращает управление либо в случае упешного выполнения, либо по истечение таймаута. Те клиент 2 может показать, что он сделал INSERT выполнив RELEASE_LOCK().

спустя 1 минуту [обр] Хаврах[досье]
Поправка: клиент 1
спустя 40 минут [обр] Алексей Севрюков(7/1292)[досье]
Хаврах[досье] Или парсить лог и смотреть там, либо писать прокладку, которая будет пропускать через себя все команды и сигнализировать об инсертах. Оба решения требуют написания отдельного софта. Вариант с логом на самом деле тоже не очень красивый, т.к. придется постоянно открывать и читать лог через какой-либо промежуток времени.
спустя 2 часа 13 минут [обр] Thirteensmay(0/157)[досье]
  1. Как предложил Алексей Севрюков[досье] - делать клиентскую прокладку. В этом случае лучше всего докрутить клиентский интерфейс к БД - в методе выполнения запроса реализовать фильтр срабатывающий на инсерты и засылающий отдельно по сетке соответствующие уведомления. Если подправить интерфейс БД не представляется возможным то написать прокладку/надстройку над ним и пользовать ее, либо просто при выполнении инсертов из клиента определить и вызывать отдельную функцию уведомлений. Отрицательный момент данного подхода - возможность рассинхронизации вследствие задержек, ошибок и пр. со всеми вытекающими.
  1. По мотивам GET_LOCK() и "парсить лог" от Алексей Севрюков[досье] - предусмотреть в БД какой нибудь простенький флажек, например на основе переменных, статусов, метаинформации, наибольших идентификаторов и тп., в крайнем случае завести маленькую табличку флагов. Устанавливать флаг сразу после инсертов. На втором клиенте по таймеру раз в N секунд проверять флаг. Запрос элементарный, нагружать сервер не будет. Конечно вариант "не концепт" зато просто.
  1. Концепт для настоящих взрослых пацанов: ;) Используя предоставляемый MySQL интерфейс динамического подключения пользовательских функций, либо исходный код MySQL, разработать свою собственную C/C++ функцию которая будет отправлять уведомления в сеть. Динамически подключать ее как пользовательскую, либо жестко слинковать как "родную" с MySQL. В этом случае функция будет доступна так же как MIN(), ABS(), CONCAT() и т.п. Т.е. просто вызывать ее по мере необходимости совместно с инсертами. По крайней мере теоретически это возможно, см. http://dev.mysql.com/doc/refman/5.0/en/adding-functions.html
спустя 15 часов [обр] Хаврах[досье]

Вариант 2 не подходит - слишком медленно и будет большая нагрузка на сеть.

Я так понял, нет никакой возможности решить задачу средствами самой СУБД. Неужели ничего нет и во взрослых базах типа Oracle или MS SQL?

спустя 9 минут [обр] Хаврах[досье]
Пока решил делать все мимо СУБД: будет сервер уведомлений, с которым все клиенты будут держать связь по tcp, параллельно соединению с базой.
спустя 1 час 8 минут [обр] GRAy(8/259)[досье]
 Неужели ничего нет и во взрослых базах типа Oracle или MS SQL?
Хаврах[досье], такой функциональности нет ни в одной из известных мне промышленных РСУБД. Видимо, на это есть свои причины. В частности - как вы собираетесь обрабатывать ситуацию с COMMIT-ROLLBACK, т.е. имеет ли смысл уведомлять другие сессии если произошёл ROLLBACK? Будет ли вас интересовать уведомления только по таблице или вы захотите наложить некие критерии на набор операций которые производятся с данными (или даже на сами данные) чтобы получать уведомления только о том, что действительно необходимо? В общем случае протоколы запросов/ответов к RDBMS серверам не предусматривают механизмов подписки-отписки на уведомления о чём-бы-то-ни-было, т.к. это добавляет существенный overhead на поддержание очереди уведомлений на клиенте и на сервере, и может, при неправильном обращении, привести к захламлению каналов связи избыточными сообщениями. Я думаю ведущие поставщики РСУБД понимают, чем такая функциональность чревата в плане поддержки и добавления точек отказа, а, возможно, и более принципиальные проблемы с ней связанные - так что, увы, решения "от производителя" вы скорее всего не найдёте. Т.к. универсального решения не предвидится - каждый решает подобные проблемы по-своему, и ,как правило, привязывается таким образом к какой-то конкретной СУБД и её "расширенным" возможностям. Если у вас что-нибудь получится, думаю всем будет интересно как вы выкрутились ;) и какие трудности испытали вне зависимости от результата.
спустя 3 часа 27 минут [обр] Хаврах[досье]

Взглянул ради интереса на документацию по Firebird, оказалось что там уже есть нужная мне функциональность, называется events (EVENT INIT/WAIT). При этом в MySQL ничего подобного нет, даже в 5.1. Так что все оказалось просто - дело в СУБД. :)

Тему можно закрывать. Спасибо всем ответившим. :)

спустя 20 часов [обр] GRAy(8/259)[досье]
Хаврах[досье] Полезно, не знал. Почитал, в принципе достаточно функционально и при этом не слишком опасно в плане неправильного использования. Некоторые сетевые проблемы не разрешимы в определённых сочетаниях типа сервера и firewall`а, но по крайней мере об этом упоминается ;). Жаль, что подобная модель не реализована нигде, кроме как в Firebird.
спустя 1 час 34 минуты [обр] GRAy(8/259)[досье]
Хаврах[досье]Хм, извиняюсь, что возможно ввёл вас в заблуждение. В своё время, когда меня интересовал подобный вопрос я натыкался в Oracle на пакеты DBMS_ALERT и DBMS_PIPE - они решают эту задачу. Мне они не подошли тогда из-за специфики Oracle Forms, но вас, скорее всего устроят. Основное отличие от firebird`а в том, что для организации механизма "слушающего" некие уведомления необходимо самостоятельно организовывать параллельное подключение к БД.
спустя 3 часа 15 минут [обр] Alexander O(10/469)[досье]
Хаврах[досье] Если обязать клиента делать инсерты только через вызов хранимой проседуры, а из нее уже слать почту или что-то в этом роде
http://www.google.com/search?q=send+mail+from+stored+procedure
спустя 39 минут [обр] Хаврах[досье]
Жаль, что подобная модель не реализована нигде, кроме как в Firebird.

GRAy[досье] Забавно получилось, а ведь ткнул пальцем наугад. :)

Alexander O[досье] Это не совсем то, мне бы хотелось и уведомления принимать от SQL-сервера.

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

Powered by POEM™ Engine Copyright © 2002-2005