Получение событий из базы данных
-
03-07-2019 - |
Вопрос
Я не очень хорошо знаком с базами данных и тем, что они предлагают за пределами операций CRUD.
Мои исследования привели меня к триггеры.В принципе, похоже, что триггеры предлагают именно такой тип функциональности:
(из Википедия)
Обычно существует три запускающих события, которые вызывают "срабатывание" триггеров:
- Событие ВСТАВКИ (при вставке новой записи в базу данных).
- Событие ОБНОВЛЕНИЯ (при изменении записи).
- Событие УДАЛЕНИЯ (при удалении записи).
Мой вопрос заключается в следующем:есть ли какой-нибудь способ, которым я могу получать уведомления в Java (предпочтительно включая измененные данные) от базы данных, когда запись обновляется / удаляется / вставляется с использованием какой-либо семантики триггера?
Каковы могут быть какие-то альтернативные решения этой проблемы?Как я могу прослушивать события базы данных?
Основная причина, по которой я хочу это сделать, - это подобный сценарий:
У меня есть 5 клиентских приложений, все в разных процессах / существующих на разных компьютерах.Все они используют общую базу данных (в данном случае Postgres).
Допустим, один клиент изменяет запись в базе данных, в которой "заинтересованы" все 5 клиентов.Я пытаюсь придумать способы, чтобы клиенты были "уведомлены" об изменении (предпочтительно с прикрепленными затронутыми данными) вместо того, чтобы они запрашивали данные с некоторым интервалом.
Решение
Используя Oracle, вы можете настроить триггер в таблице, а затем заставить триггер отправить сообщение JMS.Oracle имеет две разные реализации JMS.Затем у вас может быть процесс, который будет "прослушивать" сообщение, используя драйвер JDBC.Я использовал этот метод для внесения изменений в мое приложение.опрос.Если вы используете базу данных Java (H2), у вас есть дополнительные опции.В моем текущем приложении (SIEM) у меня есть триггеры в H2, которые публикуют события изменения с использованием JMX.
Другие советы
Не путайте базу данных (которая содержит данные) и события, связанные с этими данными.
Триггеры - это один из способов, но обычно у вас в приложении будет уровень персистентности.Этот уровень может запускать события, когда происходят определенные вещи - скажем, в теме JMS.
Триггеры - это крайняя мера, поскольку тогда вы работаете с реляционными элементами, а не с "событиями" в данных.(Например, "обновление" на самом деле может соответствовать событию "компания изменила юридическое название") Если вы полагаетесь на базу данных, вам придется сопоставлять вставки и обновления с реальными событиями....о котором вы уже знали!
Затем вы можете наложить поверх этих уведомлений другие материалы - например, обработку потока событий, - чтобы найти события, которые интересуют других.
Джеймс
Хмм.Итак, вы используете PostgreSQL и хотите "прослушивать" события и получать "уведомления" о их возникновении?
http://www.postgresql.org/docs/8.3/static/sql-listen.html http://www.postgresql.org/docs/8.3/static/sql-notify.html
Надеюсь, это поможет!
Вызов внешних процессов из базы данных сильно зависит от поставщика.
Просто у меня в голове не укладывается:
SQLServer может вызывать программы CLR из триггеров,
postgresql может вызывать произвольные функции C загружаемые динамически,
MySQL может вызывать произвольные функции C, но они должны быть скомпилированы в,
Sybase может выполнять системные вызовы, если это настроено .
Самое простое, что можно сделать, это заставить триггеры insert / update / delete внести запись в какую-нибудь таблицу журнала, и пусть ваша java-программа отслеживает эту таблицу.Хорошими столбцами для вашей таблицы журналов были бы такие вещи, как EVENT_CODE, LOG_DATETIME и LOG_MSG.
Если только вам не требуется очень высокая производительность или не нужно обрабатывать 100 тысяч записей, этого, вероятно, достаточно.
Я думаю, вы путаете две вещи.Они оба сильно зависят от поставщика БД.
Первый я назову "триггерами".Я уверен, что есть по крайней мере один поставщик БД, который считает, что триггеры отличаются от этого, но потерпите меня.Триггер - это фрагмент кода на стороне сервера, который может быть прикреплен к таблице.Например, вы могли бы запускать хранимую процедуру PSQL при каждом обновлении в таблице X.Некоторые базы данных позволяют вам записывать их на реальных языках программирования, другие - только на их варианте SQL.Триггеры, как правило, достаточно быстры и масштабируемы.
Другое я буду называть "событиями".Это триггеры, которые срабатывают в базе данных и позволяют вам определить обработчик событий в вашей клиентской программе.Т.е. каждый раз, когда появляются обновления в базе данных клиентов, запускайте updateClientsList в вашей программе.Например, используя python и firebird, смотрите http://www.firebirdsql.org/devel/python/docs/3.3.0/beyond-python-db-api.html#database-event-notification
Я полагаю, что предыдущее предложение использовать монитор является эквивалентным способом реализовать это с использованием какой-либо другой базы данных.Может быть, oracle?Службы уведомлений MSSQL, упомянутые в другом ответе, также являются другой реализацией этого.
Я бы зашел так далеко, что сказал, что вам лучше действительно знать, почему вы хотите, чтобы база данных уведомляла вашу клиентскую программу, в противном случае вам следует придерживаться триггеров на стороне сервера.
То, что вы спрашиваете, полностью зависит как от используемой вами базы данных, так и от платформы, которую вы используете для взаимодействия с вашей базой данных.
Если вы используете что-то вроде Hibernate в качестве уровня сохраняемости, у него есть набор прослушивателей и перехватчиков, которые вы можете использовать для отслеживания записей, поступающих в базу данных и из нее.
Здесь есть несколько различных методов, в зависимости от используемой вами базы данных.Одна из идей заключается в опросе базы данных (чего, я уверен, вы пытаетесь избежать).В принципе, вы могли бы время от времени проверять наличие изменений.
Другим решением (если вы используете SQL Server 2005) является использование служб уведомлений, хотя эта технология предположительно заменяется в SQL 2008 (мы еще не видели чистой замены, но Microsoft публично говорила об этом).
Если вы используете Oracle, ознакомьтесь с этим предыдущее сообщение.
Обычно для этого и предназначено стандартное клиент-серверное приложение.Если все вставки / обновления/ удаления проходят через серверное приложение, которое затем изменяет базу данных, то клиентским приложениям гораздо проще узнать, какие изменения были внесены.
Если вы используете postgresql, у него есть возможность прослушивания уведомления от клиента JDBC.
Я бы предложил использовать столбец timestamp, последний обновленный, вместе с, возможно, пользователем, обновляющим запись, а затем позволить клиентам сверять временную метку своей локальной записи с меткой сохраненной записи.
Дополнительная сложность добавления функциональности обратного вызова / запуска, на мой взгляд, просто не стоит того, если она не поддерживается серверной частью базы данных и используемой клиентской библиотекой, как, например, службы уведомлений, предлагаемые для SQL Server 2005, используемые вместе с ADO.NET.