使用Java进行数据库轮询

时间:2010-02-27 18:14:00

标签: java

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

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

7 个答案:

答案 0 :(得分:8)

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

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

答案 1 :(得分:6)

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

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

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

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

答案 2 :(得分:3)

我们在公司完成了这项工作,方法是向数据库表添加触发器,调用可执行文件来发出Tib Rendezvous消息,该消息由所有感兴趣的Java应用程序接收。

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

答案 3 :(得分:1)

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

答案 4 :(得分:1)

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

答案 5 :(得分: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 TimerTaskScheduledExecutorService 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;

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

答案 6 :(得分:0)

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

这是我的建议:

  1. 带有pk到事务和插入时间戳的新工作表
  2. 与事务表+审计列具有相同列的新审计表
  3. 触发事务表以将所有插入/更新/删除转储到审计表
  4. Java流程,用于轮询工作表,加入审计表,发布有问题的事件并从工作表中删除。
  5. 问题是:您使用什么进行投票?石英矫枉过正吗?如何根据当前的DB负载缩减轮询频率?