使用Java的数据库轮询

使用Java的数据库轮询,java,Java,我被困在某个点上,需要在Java代码中获得数据库更改。请求是在数据库的任何表中更新、添加、删除任何记录;应该被Java程序识别。如何实现它?还是Java线程 更新:感谢大家的支持,我正在使用Oracle作为DB和Weblogic 10.3研讨会。事实上,我想从一个我只有阅读权限的表中获取更新,各位,你们有什么建议吗。我无法更新数据库。我唯一能做的就是读取数据库,如果表中有任何更改,我必须获得信息/通知,说明某些数据行已被添加/删除或更新。除非数据库可以向Java发送消息,否则您必须有一个轮询线程

我被困在某个点上,需要在Java代码中获得数据库更改。请求是在数据库的任何表中更新、添加、删除任何记录;应该被Java程序识别。如何实现它?还是Java线程


更新:感谢大家的支持,我正在使用Oracle作为DB和Weblogic 10.3研讨会。事实上,我想从一个我只有阅读权限的表中获取更新,各位,你们有什么建议吗。我无法更新数据库。我唯一能做的就是读取数据库,如果表中有任何更改,我必须获得信息/通知,说明某些数据行已被添加/删除或更新。

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


一个更好、更有效的模型应该是根据更改触发事件的模型。一个内部运行Java的数据库(例如Oracle)可以做到这一点。

我们公司通过向数据库表添加触发器来实现这一点,这些触发器调用可执行文件来发出Tib会合消息,所有感兴趣的Java应用程序都会收到该消息


但是,实现此IMHO的理想方法是在应用程序级别完全控制所有数据库写入,并在此时通知任何相关方(通过多播、Tib等)。实际上,如果您有许多不同的系统,这并不总是可能的。

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

因此EJB计时器线程调用一个过程,该过程捕获标记为“未处理”的行

肮脏,但也非常简单和健壮。特别是,在崩溃或其他情况下,它仍然可以从崩溃的地方恢复,而不会有太多的复杂性


缺点是数据库上浪费了负载,而且响应时间有限(可能需要几秒钟)。

我假设您所说的情况是任何东西都可以更新表。如果由于某种原因,您讨论的是一种情况,即只有Java应用程序将更新不同的表。如果您只使用Java,则可以将此代码放在DAO或EJB中进行更新(在本例中,这比使用触发器要干净得多)。

另一种方法是通过web服务API或JMS API(执行实际的数据库调用)来完成所有数据库调用。进程可以在那里注册以获得数据库更新的通知。

您确实取决于相关数据库是否支持它。您还需要考虑开销。大量的插入/更新也意味着大量的通知,您的Java代码必须一致地处理它们,否则它将冒泡

如果datamodel允许,只需添加一个额外的列,该列保存一个时间戳,该时间戳在每次插入/更新时都会更新。大多数主要数据库支持在每次插入/更新时自动更新列。我不知道您使用的是哪台DB服务器,所以我只给出一个针对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
。您只需执行
插入mytable(somevalue)值(?)
更新mytable SET somevalue=?其中id=?
数据库将发挥神奇的作用

在确保DB服务器的时间和Java应用程序的时间相同后,您只需启动一个后台线程(使用with、or或with or),该线程大致执行以下操作:

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查询,将当前数据从结果中排除。

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

以下是我的建议:

  • 具有pk to transaction和插入时间戳的新工作表
  • 与事务表+审核列具有相同列的新审核表
  • 触发事务表,将所有插入/更新/删除转储到审核表
  • Java进程轮询工作表、加入审核表、发布有问题的事件并从工作表中删除

  • 问题是:你们用什么来投票?石英是否过量?如何根据当前的数据库负载缩减轮询频率?

    在更改时触发事件的产品示例是什么?我从来没见过。听起来像是一个数据库触发器,但它不是运行SQL(即:PL/SQL),而是运行一个实现某些接口的Java类。正确,并且不是编写自己的线程系统,而是使用Java的执行器,这将使您的生活更简单。+1表示“在应用程序级别完全控制所有数据库写入”。服务应该拥有和控制自己的数据。DBMS的主要目的是以统一的方式为多个应用程序提供对数据的访问。这包括尚未想到、更不用说实现的应用程序。它排除了单个应用程序控制所有数据的可能性。或者,如果您确实生成了执行所有数据库操作的单个应用程序,那么您将使用“真正的DBMS”作为存储引擎,“单个应用程序”作为所有应用程序的DBMS接口。“但这几乎是多余的。”乔纳森·莱弗——不,不一定。DBMS的要点是持久性。如果未来的应用程序需要数据,他们可以通过所有者获取数据。这就是服务的意义所在。这是亚马逊首席技术官沃纳·沃格斯(Werner Vogels)的观点:@duffymo:同意。此外,我还看到了混合解决方案,其中