无限循环数据库检查

Posted

技术标签:

【中文标题】无限循环数据库检查【英文标题】:infinite loop database check 【发布时间】:2013-05-14 05:39:46 【问题描述】:

我正在使用 JDBC,需要不断检查数据库是否有变化的值。

我目前有一个无限循环运行,内部循环迭代一个变化的值,每次迭代都检查数据库。

public void runInBG()  //this method called from another thread
    while(true) 
     while(els.hasElements()) 
      Test el = (Test)els.next();
       String sql = "SELECT * FROM Test WHERE id = '" + el.getId() + "'";
       Record r = db.getTestRecord(sql);//this function makes connection, executeQuery etc...and return Record object with values
       if(r != null) 
         //do something
       
     
    

我认为这不是最好的方法。

我想的另一种方式是相反的,继续迭代数据库。

更新

感谢您提供有关计时器的反馈,但我认为它不会解决我的问题。 一旦数据库发生变化,我需要根据变化的值(示例代码中的“els”)几乎立即处理结果。

即使数据库没有变化,它仍然需要不断检查变化的值。

更新 2

好的,对于任何对答案感兴趣的人,我相信我现在有了解决方案。基本上解决方案不是为此使用数据库。加载、更新、添加等……只需要从数据库到内存。 这样您就不必经常打开和关闭数据库,您只需在对数据库进行更改时处理数据库,并将这些更改反映到内存中,并且只处理当时内存中的任何内容。 当然,这会占用更多内存,但性能是这里的绝对关键。

至于定期的“计时器”答案,很抱歉,但这根本不对。没有人回答为什么使用计时器可以解决这种特殊情况。

但再次感谢您的反馈,它仍然很有帮助。

【问题讨论】:

(+1) 好问题...我能看到这样做的唯一方法是在数据库端添加某种触发器。我也不喜欢这样,因为它不受程序的控制,可能过于具体。 您的应用程序控制是否也更新和插入? 是的,Peeyush。我编写了类来处理所有数据库交互。 嗨 Jaco,请查看更新的解决方案。 您应该发布 update2 作为答案并接受它! 【参考方案1】:

另一种可能性是使用ScheduledThreadPoolExecutor

您可以实现一个包含您的逻辑的Runnable,并将其注册到ScheduledExecutorService,如下所示:

ScheduledThreadPoolExecutor executor = new ScheduledThreadPoolExecutor(10);
executor.scheduleAtFixedRate(myRunnable, 0, 5, TimeUnit.SECONDS);

上面的代码创建了一个ScheduledThreadPoolExecutor,它的池中有10个线程,并注册了一个Runnable,它将在5秒内立即开始运行。


要安排您的可运行文件,您可以使用:

scheduleAtFixedRate

创建并执行一个周期性动作,该动作在给定的初始延迟后首先启用,然后在给定的周期内启用;也就是说,执行将在 initialDelay 之后开始,然后是 initialDelay+period,然后是 initialDelay + 2 * period,依此类推。

scheduleWithFixedDelay

创建并执行一个周期性操作,该操作首先在给定的初始延迟之后启用,随后在一个执行的终止和下一个执行的开始之间具有给定的延迟。


和here你可以看到ThreadPoolExecutor的优点,看看它是否符合你的要求。我建议这个问题:Java Timer vs ExecutorService? 也是为了做出正确的决定。

【讨论】:

【参考方案2】:

while(true) 保留在runInBG() 中是个坏主意。你最好去掉那个。相反,您可以使用 Scheduler/Timer(使用 Timer 和 TimerTask)定期调用 runInBG() 并检查数据库中的更新。

【讨论】:

你可以跳过TimerTimerTask 的编码,方法是使用像quartz这样处理计划操作的框架 同意使用调度程序进行调度是可行的方法,但是由于 OP 没有提到使用第三方库的任何内容,因此使用标准 java 类似乎是一个不错的选择!如果 OP 可以使用 3p 库,则可以稍后实施调度! 仅供参考,我自己是 Quartz 用户! :) 仅仅添加信息以防手动配置Timer 会让人头疼,因为像这样的框架已经处理了很多问题。是的,我是石英用户(免责声明:我与图书馆开发无关,也与任何客户支持无关,只是一个快乐的用户)。 这必须不断检查,因为当数据库中发生任何更改时,必须处理结果。我不明白如何使用计时器来解决这个问题。【参考方案3】:

你可以使用计时器--->

Timer timer = new Timer("runInBG");

    //Taking an instance of class contains your repeated method.
    MyClass t = new MyClass();

    timer.schedule(t, 0, 2000);

【讨论】:

【参考方案4】:

正如您在上面的评论中所说,如果应用程序控制更新和插入,那么您可以创建一个框架来通知“BG”线程或进程有关数据库中的更改。通知可以通过网络通过 JMS 或使用观察者模式的内部 VM 或本地和远程通知。

你可以有通用的通知消息(它可以是本地通知的类或远程通知的文本消息)

<Notification> 
  <Type>update/insert</Type>
  <Entity>
     <Name>Account/Customer</Name>
     <Id>id</Id>
  <Entity> 
</Notification>

【讨论】:

【参考方案5】:

为了避免“忙循环”,我会尝试使用触发器。 H2 还支持DatabaseEventListener API,这样您就不必为每个表创建触发器。

这可能并不总是有效,例如,如果您使用远程连接。

【讨论】:

【参考方案6】:

更新 2

好的,对于任何对答案感兴趣的人,我相信我现在有了解决方案。基本上解决方案不是为此使用数据库。加载、更新、添加等……只需要从数据库到内存。这样您就不必经常打开和关闭数据库,您只需在对数据库进行更改时处理数据库,并将这些更改反映到内存中,并且只处理当时内存中的任何内容。当然,这会占用更多内存,但性能是这里的绝对关键。

【讨论】:

以上是关于无限循环数据库检查的主要内容,如果未能解决你的问题,请参考以下文章

检查空无限循环中的选项与做一些无限循环

尝试使用 Swift 实现无限滚动时陷入无限循环

text 无限循环2通常用于检查输入验证

当我想检查窗口对象的属性是不是在这里时,useEffect 中的无限循环

appium 检查器中的无限循环

用 cin 检查用户整数输入会产生无限循环