2010-02-27 2 views
5

Я застрял в какой-то момент, когда мне нужно получить изменения базы данных в Java-коде. Запрос состоит в том, чтобы обновить, добавить, удалить любую запись в любой таблице db; должны быть распознаны программой Java. Как можно реализовать JMS? или поток Java?Опрос базы данных с использованием Java

Обновление: Спасибо, ребята, за вашу поддержку. Я фактически использую Oracle в качестве базы данных DB и Weblogic 10.3. На самом деле я хочу получать обновления из таблицы, в которой у меня есть только разрешение на чтение, так что ребята, что вы все предлагаете. Я не могу обновить БД. Единственное, что я могу сделать, это просто прочитать БД и, если есть какие-либо изменения в таблице, я должен получить информацию/уведомление о том, что некоторые строки данных были добавлены/удалены или обновлены.

+0

Обновление копируется спамом с обмана: http://stackoverflow.com/questions/2363697/database-polling-using-java-closed – BalusC

+0

Возможно, данные об изменении данных Oracle могут быть получены? –

+0

Только если вы работаете с Oracle DB: [http://stackoverflow.com/questions/21177723/how-to-call-java-class-from-oracle-trigger](http://stackoverflow.com/ вопросы/21177723/how-to-call-java-class-from-oracle-trigger) –

ответ

8

Если база данных не может отправить сообщение на Java, вам нужно будет опросить этот поток.

Лучшая, более эффективная модель будет той, которая вызывает события при изменениях. База данных, в которой есть Java, работающая внутри (например, Oracle), может это сделать.

+1

Какой пример продукта, который вызывает события при внесении изменений? Я этого никогда не видел. Звучит как триггер базы данных, но вместо запуска SQL (т. Е. PL/SQL) он запускает класс Java, который реализует некоторый интерфейс. –

+0

Исправьте, и вместо того, чтобы писать собственную систему потоков, используйте исполнителей Java, что сделает вашу жизнь намного проще. –

3

Мы достигли этого в нашей фирме, добавив триггеры в таблицы базы данных, которые вызывают исполняемый файл для выпуска сообщения Tib Rendezvous, которое получено всеми заинтересованными Java-приложениями.

Однако идеальный способ сделать это IMHO - это полностью контролировать все записи базы данных на уровне приложений и уведомлять об этом любые заинтересованные стороны (через multi-cast, Tib и т. Д.). На самом деле это не всегда возможно, когда у вас есть несколько разрозненных систем.

+0

+1 для «полного контроля над всеми базами данных на уровне приложений». Служба должна владеть и контролировать свои собственные данные. – duffymo

+2

Основная задача СУБД - обеспечить доступ к данным для нескольких приложений единообразным способом. Это включает в себя приложения, которые пока еще не приняты, а тем более реализованы. Это исключает возможность того, что одно приложение контролирует все данные. Или, если вы создаете одно приложение, выполняющее все операции с базой данных, тогда вы используете «реальную СУБД» как механизм хранения и «одно приложение» в качестве интерфейса СУБД для всех приложений. Но это близко к избыточному. –

+0

@ Джонатан Леффер - Нет, не обязательно. Главной точкой СУБД является настойчивость. Если будущие, немыслимые приложения нуждаются в данных, они могут пройти через владельца, чтобы получить его. Вот что такое услуги.Это мнение Вернера Фогельса, технического директора Amazon: http://queue.acm.org/detail.cfm?id=1142065 – duffymo

6

Мы делаем это путем опроса БД с помощью задачи таймера EJB. По сути, у нас есть статус, который мы обновляем, когда обрабатываем эту строку.

Таким образом, поток таймера EJB вызывает процедуру, которая захватывает строки, которые помечены как «необработанные».

Грязные, но также очень простые и надежные. Особенно, после крушения или чего-то еще, он все равно может подняться с того места, где он разбился без излишней сложности.

Недостатком является потерянная нагрузка на БД, а также время отклика будет ограничено (возможно, потребуются секунды).

1

Я предполагаю, что вы говорите о ситуации, когда что-либо может обновить таблицу. Если по какой-то причине вы говорите о ситуации, когда только приложение Java будет обновлять таблицу, которая отличается. Если вы используете только Java, вы можете поместить этот код в свой DAO или EJB, выполнив обновление (в этом случае он намного чище, чем использование триггера).

1

Альтернативный способ сделать это - вызвать все вызовы базы данных через API веб-службы или, возможно, JMS API, который выполняет фактические вызовы базы данных. Процессы могли зарегистрироваться там, чтобы получить уведомление об обновлении базы данных.

1

Вы действительно зависите от поддержки этой базы данных. Вам также необходимо учитывать накладные расходы. Множество вставок/обновлений также означает много уведомлений, и ваш Java-код должен обрабатывать их последовательно, иначе он будет пузыриться.

Если это позволяет датемодель, просто добавьте дополнительный столбец, который содержит временную метку, которая обновляется при каждой вставке/обновлении. Большинство основных БД поддерживают автоматическое обновление столбца при каждом вставке/обновлении.Я не знаю, какой сервер БД вы используете, так что я дам только MySQL целенаправленный примера:

CREATE TABLE mytable (
    id BIGINT NOT NULL AUTO_INCREMENT PRIMARY KEY, 
    somevalue VARCHAR(255) NOT NULL, 
    lastupdate TIMESTAMP NOT NULL DEFAULT CURRENT_TIMESTAMP ON UPDATE CURRENT_TIMESTAMP, 
    INDEX (lastupdate) 
) 

Таким образом, вам не нужно беспокоиться о вставке/обновлении в lastupdate себя. Вы можете просто сделать INSERT INTO mytable (somevalue) VALUES (?) или UPDATE mytable SET somevalue = ? WHERE id = ?, и БД сделает магию.

Убедившись, что время сервер БД и времени Java приложения являются такими же, вы можете просто стрелять фоновый поток (с использованием либо Timer с TimerTask или ScheduledExecutorService с Runnable или Callable), который делает примерно так:

Date now = new Date(); 
statement = connection.prepareStatement("SELECT id FROM mytable WHERE lastupdate BETWEEN ? AND ?"); 
statement.setDate(1, this.lastTimeChecked); 
statement.setDate(2, now); 
resultSet = statement.executeQuery(); 
while (resultSet.next()) { 
    // Handle accordingly. 
} 
this.lastTimeChecked = now; 

Обновление: согласно обновлению вопроса выясняется, что у вас нет контроля над БД. Ну, тогда у вас нет хороших/эффективных вариантов. Либо просто обновите весь список в Java-памяти целыми данными из БД без проверки/сравнения изменений (возможно, самого быстрого способа) или динамического создания SQL-запроса на основе текущих данных, что исключает текущие данные из результатов.

0

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

Вот мое предложение:

  1. новый рабочий стол с рк к транзакции и вставить метки времени
  2. Новая таблица аудита, которая имеет то же столбцы, как сделка таблица + аудит столбцы
  3. Trigger по таблице транзакций для dump all insert/update/delete to a audit table
  4. Процесс Java для опроса рабочей таблицы, присоединения к таблице аудита, публикации рассматриваемого события и удаления из рабочей таблицы.

Вопрос: Что вы используете для опроса? Является ли кварц излишним? Как вы можете уменьшить частоту опроса на основе текущей нагрузки БД?

Смежные вопросы