使用Java进行数据库轮询

我被困在某些地方,我需要在Java代码中获得数据库更改。 请求是在db的任何表中更新,添加,删除任何记录; 应该被Java程序识别。 怎么可以实现JMS? 还是Java线程?

更新:感谢大家的支持我实际上使用Oracle作为DB和Weblogic 10.3研讨会。 实际上我想从一张表中获取更新,我只有读取权限,所以你们都建议你们。 我无法更新数据库。 我唯一能做的就是读取数据库,如果表中有任何变化,我必须得到某些数据行已被添加/删除或更新的信息/通知。

除非数据库可以向Java发送消息,否则您必须有一个轮询的线程。

一个更好,更有效的模型将是一个触发变化事件的模型。 内部运行Java的数据库(例如Oracle)可以做到这一点。

我们通过使用EJB计时器任务轮询数据库来实现。 从本质上讲,我们有一个状态字段,我们在处理该行时会更新。

因此,EJB计时器线程调用一个过程来抓取标记为“未处理”的行。

脏,但也非常简单和强大。 特别是在发生碰撞事故之后,它仍然可以从崩溃的地方捡到,而不会有太多的复杂性。

缺点是DB上的浪费负载,并且响应时间也将受到限制(可能需要几秒钟)。

我们在公司中通过向数据库表添加触发器来完成此操作,该数据库表调用可执行文件来发出Tib Rendezvous消息,该消息由所有感兴趣的Java应用程序接收。

但是,执行此操作的理想方法是在应用程序级别完全控制所有数据库写入,并在此时通知任何感兴趣的各方(通过多播,Tib等)。 实际上,如果您拥有许多不同的系统,这并不总是可行的。

我假设你在谈论任何事情都可以更新表格的情况。 如果出于某种原因,您正在谈论只有Java应用程序将更新不同表的情况。 如果您只使用Java,则可以将此代码放在DAO或EJB中进行更新(在这种情况下,它比使用触发器要清晰得多)。

另一种方法是通过Web服务API或实际数据库调用的JMS API来汇集所有数据库调用。 进程可以在那里注册以获取数据库更新的通知。

您确实依赖于所讨论的数据库是否支持它。 您还需要考虑开销。 很多插入/更新也意味着很多通知,你的Java代码必须一致地处理它们,否则它会冒出来。

如果datamodel允许,只需添加一个额外的列,该列包含一个时间戳,该时间戳在每次插入/更新时都会更新。 大多数主要数据库都支持在每次插入/更新时自动更新列。 我不知道你使用的是哪个数据库服务器,所以我只给出一个以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 = ? UPDATE mytable SET somevalue = ? WHERE id = ? 并且DB会做出魔术。

在确保数据库服务器的时间和Java应用程序的时间相同之后,您可以启动后台线程(使用带有TimerTask Timer或带有RunnableCallable ScheduledExecutorService ),这大致如下:

 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; 

更新 :根据问题更新,事实certificate您无法控制数据库。 那么,你没有太多好/有效的选择。 只需使用来自数据库的整个数据刷新Java内存中的整个列表,而无需检查/比较更改(可能是最快的方法),或者根据当前数据动态生成SQL查询,该数据会从结果中排除当前数据。

我们有类似的要求。 在我们的案例中,我们有一个遗留系统,我们不希望对现有事务表的性能产生负面影响。

这是我的建议:

  1. 带有pk到事务和插入时间戳的新工作表
  2. 一个新的审计表,其列与事务表+审计列相同
  3. 触发事务表以将所有插入/更新/删除转储到审计表
  4. Java进程轮询工作表,加入审计表,发布有问题的事件并从工作表中删除。

问题是:你用什么来进行投票? 石英矫枉过正吗? 如何根据当前数据库负载缩减轮询频率?