无限循环数据库检查

时间:2013-05-14 05:39:47

标签: java sql jdbc h2

我正在使用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

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

关于定期的“计时器”答案,我很抱歉,但这根本不对。没有人回答是有理由如何使用计时器来解决这种特殊情况。

但是再次感谢您的反馈,但它仍然有用。

6 个答案:

答案 0 :(得分:3)

另一种可能性是使用ScheduledThreadPoolExecutor

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

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

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


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

scheduleAtFixedRate

  

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

scheduleWithFixedDelay

  

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


here您可以看到ThreadPoolExecutor的优势,以确定它是否符合您的要求。我也提出这个问题:Java Timer vs ExecutorService?以便做出正确的决定。

答案 1 :(得分:1)

while(true)保留在runInBG()中是一个坏主意。你最好删除它。相反,您可以使用计划程序/计时器(使用Timer&amp; TimerTask)定期调用runInBG()并检查数据库中的更新。< / p>

答案 2 :(得分:1)

你可以使用计时器---&gt;

Timer timer = new Timer("runInBG");

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

    timer.schedule(t, 0, 2000);

答案 3 :(得分:0)

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

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

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

答案 4 :(得分:0)

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

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

答案 5 :(得分:0)

更新2

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