Мониторинг вставки MySQL из разных приложений

В настоящее время у меня есть веб-сервис, который вставляет информацию в базу данных mysql с помощью Hibernate. Некоторая часть этой информации должна обрабатываться другим приложением "импорт". Я бы не хотел запускать это приложение из webservice. Таким образом, веб-сервис не имеет зависимости от веб-службы и наоборот.

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

Изменить *

Короче говоря, ответ, который я хотел бы иметь; Возможно ли отслеживать изменения в базе данных/таблице mysql (исходящие из любого источника) из приложения java, которое не изменяет сама база данных/таблицы

Обновление Bounty *

Я награжу награду человеку, который может объяснить мне, как отслеживать изменения, внесенные в таблицу/базу данных MySQL, с помощью приложения Java. Приложение Java, отслеживающее изменения, не является приложением, вносящим какие-либо изменения. Источником изменений может быть что угодно.

Ответ 1

Вы можете прочитать бинарный журнал mysql. Здесь вы можете найти некоторую информацию. Существует java parser и другой - но это отмеченные как незавершенные), вы также можете искать аналогичные парсеры, используя другие языки (например, perl) и переписать их на Java.
Также посмотрите mysql-proxy.

Ответ 2

Я думаю, что вы могли бы добиться чего-то подобного довольно легко, предполагая, что вы не возражаете создать несколько дополнительных таблиц и триггеров в своей базе данных и что приложение-приложение мониторинга должно будет опросить базу данных, а не специально получать триггеры.

Предполагая, что таблица, которую вы хотите контролировать, выглядит примерно так:

CREATE TABLE ToMonitor ( id INTEGER PRIMARY KEY, value TEXT );

Затем вы создаете таблицу для отслеживания изменений и триггер, который заполняет эту таблицу:

CREATE TABLE InsertedRecords( value TEXT );
CREATE TRIGGER trig AFTER INSERT ON account
FOR EACH ROW INSERT INTO InsertedRecords( value ) VALUES ( NEW.value );

Это приведет к заполнению таблицы InsertedRecords каждой вставкой, которая происходит в ToMonitor.

Затем вам просто нужно настроить свое приложение для мониторинга на периодический SELECT * from InsertedRecords, предпринять соответствующие действия и затем удалить записи из InsertedRecords

EDIT: небольшая альтернатива, если вы не против немного кодирования C/С++, будет следовать инструкциям здесь создать пользовательскую функцию SQL, которая запустила ваше приложение мониторинга в действие, а затем просто вызовет эту функцию SQL из созданного вами триггера.

Ответ 3

Я знаю, что это не то, что вы просили (таким образом, это не правильный ответ), но если вы подумаете о том, чтобы отказаться от идеи "позволить БД уведомлять приложения", вы получаете идеальный вариант для использования JMS для связи между приложениями,

Ваше приложение, инициировавшее изменение, может опубликовать сообщение в теме JMS, которая подписана вторым приложением. После первого изменения базы данных он помещает сообщение в эту тему. Затем второй видит это новое событие и действует соответствующим образом. Вы даже можете опубликовать дельта в сообщении, чтобы второе приложение не нуждалось в доступе к базе данных.

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

Если вы просто используете JMS-сервер между этими двумя приложениями, вы можете добавить третье приложение в будущем, которое просто слушает этот раздел (и публикует новое сообщение, если оно имеет доступ на запись к db) и другие приложения даже не должны знать, что там есть еще одно приложение. Не база данных.

Ответ 4

Предположим, мы хотим отслеживать изменения в таблице 'table1'

CREATE TABLE `table1` (
    `id` INT(10) NOT NULL AUTO_INCREMENT,
    `value` VARCHAR(50) NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=10;

выше - это запрос для создания 'table1', который содержит столбец 'id', который является автоматическим приращением

создать другую таблицу для хранения изменений. Запрос приведен ниже

CREATE TABLE `changes` (
    `id` INT(10) NOT NULL AUTO_INCREMENT,
    `changes` VARCHAR(200) NULL DEFAULT '0',
    `change_time` TIMESTAMP NULL DEFAULT NULL,
    `tablename` VARCHAR(50) NULL DEFAULT NULL,
    `changed_id` VARCHAR(10) NULL DEFAULT NULL,
    PRIMARY KEY (`id`)
)
COLLATE='latin1_swedish_ci'
ENGINE=InnoDB
AUTO_INCREMENT=21;

теперь создайте триггер в первой таблице, то есть.. 'table1' Запрос приведен ниже

delimiter |
create trigger trg_table1 AFTER INSERT ON table1
FOR EACH ROW BEGIN
DECLARE lastid INT DEFAULT 0;
SELECT max(id) INTO lastid from table1;
insert into changes values(null,'insert',now(),'table1',lastid);
end;
|
delimiter ;

Теперь, если вы попытаетесь вставить что-либо в 'table1', его данные будут автоматически вставлены в таблицу изменений.  В изменении таблицы изменений указывается тип изменения, то есть.. вставка, обновление и т.д.                 change_time указывает время, в которое происходят изменения                 tablename указывает таблицу, в которой происходят изменения                 Измененный_ID указывает идентификатор вновь вставленной строки в 'table1'

Теперь создайте java-программу, которая непрерывно читает таблицу "changes". Новая запись в таблице "changes" означает, что что-то случилось с базой данных. Из каждой записи в таблице "изменения" вы можете понять, в какой таблице произошла операция вставки. И на основе этого вы можете выполнить соответствующие действия. После выполнения соответствующей операции удалите эту строку из таблицы "changes".

Вы можете создать триггер (как я сделал выше) для каждой таблицы в вашей базе данных... Из столбца "tablename" таблицы "changes" вы можете понять, что вставка произошла в какой таблице.

Ответ 5

Вы можете использовать решение для массового обслуживания, такое как Q4M, но в вашей ситуации это может быть излишним. Но вы могли:

В базе данных MySQL добавьте столбец timestamp в таблицу, в которую вставляется. В приложении "import" используйте java.util.timer или внешний планировщик, например cron. Используйте один из них для запуска задачи, которая читает таблицу вставки, где столбец временной метки равен нулю. Возьмите соответствующее действие для этих строк, а затем установите столбец timestamp со значением. Если строк с нулевой меткой времени нет, у вас нет новых вставок. Простой, но он работает.

Возможно, вы захотите добавить индекс в столбец timestamp по соображениям производительности.